refactoring files to be located by feature

This commit is contained in:
2025-07-23 09:23:44 -06:00
parent 46e0c36916
commit c95c40f9e7
75 changed files with 279 additions and 303 deletions

View File

@@ -22,7 +22,7 @@ import {
} from "@/hooks/localCourse/storageDirectoryHooks"; } from "@/hooks/localCourse/storageDirectoryHooks";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel"; import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel"; import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType"; import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import { import {
DayOfWeek, DayOfWeek,
LocalCourseSettings, LocalCourseSettings,

View File

@@ -1,4 +1,4 @@
import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/assignmentMarkdownSerializer"; import { assignmentMarkdownSerializer } from "@/features/local/assignments/models/utils/assignmentMarkdownSerializer";
import { groupByStartDate } from "@/models/local/utils/timeUtils"; import { groupByStartDate } from "@/models/local/utils/timeUtils";
import { fileStorageService } from "@/services/fileStorage/fileStorageService"; import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";

View File

@@ -2,10 +2,8 @@
import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment"; import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment";
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel"; import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel"; import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { import {
dateToMarkdownString, dateToMarkdownString,
getDateFromStringOrThrow, getDateFromStringOrThrow,
@@ -13,6 +11,8 @@ import {
import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils";
import { htmlIsCloseEnough } from "@/services/utils/htmlIsCloseEnough"; import { htmlIsCloseEnough } from "@/services/utils/htmlIsCloseEnough";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export const getStatus = ({ export const getStatus = ({
item, item,

View File

@@ -2,9 +2,7 @@
import { useCanvasAssignmentsQuery } from "@/hooks/canvas/canvasAssignmentHooks"; import { useCanvasAssignmentsQuery } from "@/hooks/canvas/canvasAssignmentHooks";
import { useCanvasPagesQuery } from "@/hooks/canvas/canvasPageHooks"; import { useCanvasPagesQuery } from "@/hooks/canvas/canvasPageHooks";
import { useCanvasQuizzesQuery } from "@/hooks/canvas/canvasQuizHooks"; import { useCanvasQuizzesQuery } from "@/hooks/canvas/canvasQuizHooks";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { import {
getDateFromStringOrThrow, getDateFromStringOrThrow,
getDateOnlyMarkdownString, getDateOnlyMarkdownString,
@@ -13,6 +11,8 @@ import { ReactNode } from "react";
import { useCalendarItemsContext } from "../../context/calendarItemsContext"; import { useCalendarItemsContext } from "../../context/calendarItemsContext";
import { getStatus } from "./getStatus"; import { getStatus } from "./getStatus";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export function useTodaysItems(day: string) { export function useTodaysItems(day: string) {
const { data: settings } = useLocalCourseSettingsQuery(); const { data: settings } = useLocalCourseSettingsQuery();

View File

@@ -1,6 +1,6 @@
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/models/local/quiz/localQuiz"; import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { createContext, useContext } from "react"; import { createContext, useContext } from "react";
export interface CalendarItemsInterface { export interface CalendarItemsInterface {

View File

@@ -1,16 +1,13 @@
"use client"; "use client";
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
import { import {
useLecturesSuspenseQuery, useLecturesSuspenseQuery,
useLectureUpdateMutation, useLectureUpdateMutation,
} from "@/hooks/localCourse/lectureHooks"; } from "@/hooks/localCourse/lectureHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; import { useUpdatePageMutation } from "@/features/local/pages/pageHooks";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { Lecture } from "@/models/local/lecture"; import { Lecture } from "@/models/local/lecture";
import { getLectureForDay } from "@/models/local/utils/lectureUtils"; import { getLectureForDay } from "@/models/local/utils/lectureUtils";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { import {
getDateFromStringOrThrow, getDateFromStringOrThrow,
getDateOnlyMarkdownString, getDateOnlyMarkdownString,
@@ -21,6 +18,9 @@ import { DraggableItem } from "./draggingContext";
import { getNewLockDate } from "./getNewLockDate"; import { getNewLockDate } from "./getNewLockDate";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useCourseContext } from "../courseContext"; import { useCourseContext } from "../courseContext";
import { useUpdateAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export function useItemDropOnDay({ export function useItemDropOnDay({
setIsDragging, setIsDragging,

View File

@@ -1,13 +1,13 @@
"use client"; "use client";
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks"; import { useUpdatePageMutation } from "@/features/local/pages/pageHooks";
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react"; import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
import { DraggableItem } from "./draggingContext"; import { DraggableItem } from "./draggingContext";
import { useCourseContext } from "../courseContext"; import { useCourseContext } from "../courseContext";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useUpdateAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export function useItemDropOnModule({ export function useItemDropOnModule({
setIsDragging, setIsDragging,

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { usePagesQueries } from "@/hooks/localCourse/pageHooks"; import { usePagesQueries } from "@/features/local/pages/pageHooks";
import { IModuleItem } from "@/models/local/IModuleItem"; import { IModuleItem } from "@/models/local/IModuleItem";
import { import {
getDateFromString, getDateFromString,
@@ -22,9 +22,9 @@ import { useCourseContext } from "../context/courseContext";
import { Expandable } from "../../../../components/Expandable"; import { Expandable } from "../../../../components/Expandable";
import { useDragStyleContext } from "../context/drag/dragStyleContext"; import { useDragStyleContext } from "../context/drag/dragStyleContext";
import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks"; import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks";
import { useAssignmentNamesQuery } from "@/hooks/localCourse/assignmentHooks";
import { useTRPC } from "@/services/serverFunctions/trpcClient"; import { useTRPC } from "@/services/serverFunctions/trpcClient";
import { useSuspenseQueries } from "@tanstack/react-query"; import { useSuspenseQueries } from "@tanstack/react-query";
import { useAssignmentNamesQuery } from "@/features/local/assignments/assignmentHooks";
export default function ExpandableModule({ export default function ExpandableModule({
moduleName, moduleName,

View File

@@ -3,11 +3,10 @@ import ButtonSelect from "@/components/ButtonSelect";
import SelectInput from "@/components/form/SelectInput"; import SelectInput from "@/components/form/SelectInput";
import TextInput from "@/components/form/TextInput"; import TextInput from "@/components/form/TextInput";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
import { useCreateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
import { useModuleNamesQuery } from "@/hooks/localCourse/localCourseModuleHooks"; import { useModuleNamesQuery } from "@/hooks/localCourse/localCourseModuleHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useCreatePageMutation } from "@/hooks/localCourse/pageHooks"; import { useCreatePageMutation } from "@/features/local/pages/pageHooks";
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup"; import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import React, { useState } from "react"; import React, { useState } from "react";
import { useCourseContext } from "../context/courseContext"; import { useCourseContext } from "../context/courseContext";
@@ -17,6 +16,7 @@ import {
dateToMarkdownString, dateToMarkdownString,
getDateFromStringOrThrow, getDateFromStringOrThrow,
} from "@/models/local/utils/timeUtils"; } from "@/models/local/utils/timeUtils";
import { useCreateAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
export default function NewItemForm({ export default function NewItemForm({
moduleName: defaultModuleName, moduleName: defaultModuleName,

View File

@@ -1,16 +1,13 @@
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import Modal, { useModal } from "@/components/Modal"; import Modal, { useModal } from "@/components/Modal";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
import { useAssignmentQuery, useDeleteAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import { import {
useCanvasAssignmentsQuery, useCanvasAssignmentsQuery,
useAddAssignmentToCanvasMutation, useAddAssignmentToCanvasMutation,
useDeleteAssignmentFromCanvasMutation, useDeleteAssignmentFromCanvasMutation,
useUpdateAssignmentInCanvasMutation, useUpdateAssignmentInCanvasMutation,
} from "@/hooks/canvas/canvasAssignmentHooks"; } from "@/hooks/canvas/canvasAssignmentHooks";
import {
useAssignmentQuery,
useDeleteAssignmentMutation,
} from "@/hooks/localCourse/assignmentHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils"; import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
import { getCourseUrl } from "@/services/urlUtils"; import { getCourseUrl } from "@/services/urlUtils";

View File

@@ -1,7 +1,7 @@
import MarkdownDisplay from "@/components/MarkdownDisplay"; import MarkdownDisplay from "@/components/MarkdownDisplay";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { rubricItemIsExtraCredit } from "@/models/local/assignment/rubricItem"; import { rubricItemIsExtraCredit } from "@/features/local/assignments/models/rubricItem";
import { assignmentPoints } from "@/models/local/assignment/utils/assignmentPointsUtils"; import { assignmentPoints } from "@/features/local/assignments/models/utils/assignmentPointsUtils";
import { formatHumanReadableDate } from "@/services/utils/dateFormat"; import { formatHumanReadableDate } from "@/services/utils/dateFormat";
import React, { Fragment } from "react"; import React, { Fragment } from "react";

View File

@@ -1,14 +1,9 @@
"use client"; "use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor"; import { MonacoEditor } from "@/components/editor/MonacoEditor";
import {
useAssignmentQuery,
useUpdateAssignmentMutation,
useUpdateImageSettingsForAssignment,
} from "@/hooks/localCourse/assignmentHooks";
import { import {
LocalAssignment, LocalAssignment,
localAssignmentMarkdown, localAssignmentMarkdown,
} from "@/models/local/assignment/localAssignment"; } from "@/features/local/assignments/models/localAssignment";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import AssignmentPreview from "./AssignmentPreview"; import AssignmentPreview from "./AssignmentPreview";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
@@ -22,6 +17,11 @@ import EditAssignmentHeader from "./EditAssignmentHeader";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
import { getAssignmentHelpString } from "./getAssignmentHelpString"; import { getAssignmentHelpString } from "./getAssignmentHelpString";
import { EditLayout } from "@/components/EditLayout"; import { EditLayout } from "@/components/EditLayout";
import {
useAssignmentQuery,
useUpdateAssignmentMutation,
useUpdateImageSettingsForAssignment,
} from "@/features/local/assignments/assignmentHooks";
export default function EditAssignment({ export default function EditAssignment({
moduleName, moduleName,

View File

@@ -5,7 +5,7 @@ import { Spinner } from "@/components/Spinner";
import { import {
useAssignmentQuery, useAssignmentQuery,
useUpdateAssignmentMutation, useUpdateAssignmentMutation,
} from "@/hooks/localCourse/assignmentHooks"; } from "@/features/local/assignments/assignmentHooks";
import { getModuleItemUrl } from "@/services/urlUtils"; import { getModuleItemUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType"; import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } from "@/models/local/localCourseSettings";
export function getAssignmentHelpString(settings: LocalCourseSettings) { export function getAssignmentHelpString(settings: LocalCourseSettings) {

View File

@@ -1,10 +1,5 @@
"use client"; "use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor"; import { MonacoEditor } from "@/components/editor/MonacoEditor";
import {
usePageQuery,
useUpdatePageMutation,
} from "@/hooks/localCourse/pageHooks";
import { localPageMarkdownUtils } from "@/models/local/page/localCoursePage";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import PagePreview from "./PagePreview"; import PagePreview from "./PagePreview";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
@@ -15,6 +10,11 @@ import { useCourseContext } from "@/app/course/[courseName]/context/courseContex
import { useAuthoritativeUpdates } from "@/app/course/[courseName]/utils/useAuthoritativeUpdates"; import { useAuthoritativeUpdates } from "@/app/course/[courseName]/utils/useAuthoritativeUpdates";
import EditPageHeader from "./EditPageHeader"; import EditPageHeader from "./EditPageHeader";
import { EditLayout } from "@/components/EditLayout"; import { EditLayout } from "@/components/EditLayout";
import { localPageMarkdownUtils } from "@/features/local/pages/localCoursePageModels";
import {
usePageQuery,
useUpdatePageMutation,
} from "@/features/local/pages/pageHooks";
export default function EditPage({ export default function EditPage({
moduleName, moduleName,

View File

@@ -11,7 +11,7 @@ import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHoo
import { import {
useDeletePageMutation, useDeletePageMutation,
usePageQuery, usePageQuery,
} from "@/hooks/localCourse/pageHooks"; } from "@/features/local/pages/pageHooks";
import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils"; import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
import { getCourseUrl } from "@/services/urlUtils"; import { getCourseUrl } from "@/services/urlUtils";
import Link from "next/link"; import Link from "next/link";

View File

@@ -1,9 +1,7 @@
import MarkdownDisplay from "@/components/MarkdownDisplay"; import MarkdownDisplay from "@/components/MarkdownDisplay";
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import React from "react"; import React from "react";
export default function PagePreview({ page }: { page: LocalCoursePage }) { export default function PagePreview({ page }: { page: LocalCoursePage }) {
return ( return <MarkdownDisplay markdown={page.text} />;
<MarkdownDisplay markdown={page.text} />
);
} }

View File

@@ -5,7 +5,7 @@ import { Spinner } from "@/components/Spinner";
import { import {
usePageQuery, usePageQuery,
useUpdatePageMutation, useUpdatePageMutation,
} from "@/hooks/localCourse/pageHooks"; } from "@/features/local/pages/pageHooks";
import { getModuleItemUrl } from "@/services/urlUtils"; import { getModuleItemUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";

View File

@@ -1,6 +1,5 @@
"use client"; "use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor"; import { MonacoEditor } from "@/components/editor/MonacoEditor";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import QuizPreview from "./QuizPreview"; import QuizPreview from "./QuizPreview";
import { QuizButtons } from "./QuizButton"; import { QuizButtons } from "./QuizButton";
@@ -13,11 +12,12 @@ import {
useUpdateQuizMutation, useUpdateQuizMutation,
} from "@/hooks/localCourse/quizHooks"; } from "@/hooks/localCourse/quizHooks";
import { useAuthoritativeUpdates } from "../../../../utils/useAuthoritativeUpdates"; import { useAuthoritativeUpdates } from "../../../../utils/useAuthoritativeUpdates";
import { extractLabelValue } from "@/models/local/assignment/utils/markdownUtils"; import { extractLabelValue } from "@/features/local/assignments/models/utils/markdownUtils";
import EditQuizHeader from "./EditQuizHeader"; import EditQuizHeader from "./EditQuizHeader";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { EditLayout } from "@/components/EditLayout"; import { EditLayout } from "@/components/EditLayout";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";
const helpString = (settings: LocalCourseSettings) => { const helpString = (settings: LocalCourseSettings) => {
const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- "); const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- ");

View File

@@ -1,10 +1,7 @@
import CheckIcon from "@/components/icons/CheckIcon"; import CheckIcon from "@/components/icons/CheckIcon";
import MarkdownDisplay from "@/components/MarkdownDisplay"; import MarkdownDisplay from "@/components/MarkdownDisplay";
import { LocalQuizQuestion, QuestionType } from "@/features/local/quizzes/models/localQuizQuestion";
import { useQuizQuery } from "@/hooks/localCourse/quizHooks"; import { useQuizQuery } from "@/hooks/localCourse/quizHooks";
import {
LocalQuizQuestion,
QuestionType,
} from "@/models/local/quiz/localQuizQuestion";
import { escapeMatchingText } from "@/services/utils/questionHtmlUtils"; import { escapeMatchingText } from "@/services/utils/questionHtmlUtils";
export default function QuizPreview({ export default function QuizPreview({

View File

@@ -4,7 +4,7 @@ import {
useLocalCourseSettingsQuery, useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation, useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks"; } from "@/hooks/localCourse/localCoursesHooks";
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup"; import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import TextInput from "../../../../components/form/TextInput"; import TextInput from "../../../../components/form/TextInput";
import { useSetAssignmentGroupsMutation } from "@/hooks/canvas/canvasCourseHooks"; import { useSetAssignmentGroupsMutation } from "@/hooks/canvas/canvasCourseHooks";

View File

@@ -7,7 +7,7 @@ import {
import { import {
AssignmentSubmissionType, AssignmentSubmissionType,
AssignmentSubmissionTypeList, AssignmentSubmissionTypeList,
} from "@/models/local/assignment/assignmentSubmissionType"; } from "@/features/local/assignments/models/assignmentSubmissionType";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { settingsBox } from "./sharedSettings"; import { settingsBox } from "./sharedSettings";

View File

@@ -1,10 +1,6 @@
"use client"; "use client";
import { useTRPC } from "@/services/serverFunctions/trpcClient"; import { useTRPC } from "@/services/serverFunctions/trpcClient";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "./localCoursesHooks";
import { import {
extractImageSources, extractImageSources,
markdownToHtmlNoImages, markdownToHtmlNoImages,
@@ -15,6 +11,10 @@ import {
useQueryClient, useQueryClient,
useSuspenseQuery, useSuspenseQuery,
} from "@tanstack/react-query"; } from "@tanstack/react-query";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
export const useAssignmentQuery = ( export const useAssignmentQuery = (
moduleName: string, moduleName: string,

View File

@@ -1,8 +1,8 @@
import publicProcedure from "../procedures/public"; import publicProcedure from "../../../services/serverFunctions/procedures/public";
import { z } from "zod"; import { z } from "zod";
import { router } from "../trpcSetup"; import { router } from "../../../services/serverFunctions/trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService"; import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { zodLocalAssignment } from "@/models/local/assignment/localAssignment"; import { zodLocalAssignment } from "@/features/local/assignments/models/localAssignment";
export const assignmentRouter = router({ export const assignmentRouter = router({
getAssignment: publicProcedure getAssignment: publicProcedure

View File

@@ -1,4 +1,4 @@
import { IModuleItem } from "../IModuleItem"; import { IModuleItem } from "../../../../models/local/IModuleItem";
import { import {
AssignmentSubmissionType, AssignmentSubmissionType,
zodAssignmentSubmissionType, zodAssignmentSubmissionType,

View File

@@ -1,7 +1,7 @@
import { import {
verifyDateOrThrow, verifyDateOrThrow,
verifyDateStringOrUndefined, verifyDateStringOrUndefined,
} from "../../utils/timeUtils"; } from "../../../../../models/local/utils/timeUtils";
import { AssignmentSubmissionType } from "../assignmentSubmissionType"; import { AssignmentSubmissionType } from "../assignmentSubmissionType";
import { LocalAssignment } from "../localAssignment"; import { LocalAssignment } from "../localAssignment";
import { RubricItem } from "../rubricItem"; import { RubricItem } from "../rubricItem";

View File

@@ -1,7 +1,7 @@
import { IModuleItem } from "@/models/local/IModuleItem";
import { verifyDateOrThrow } from "@/models/local/utils/timeUtils";
import { z } from "zod"; import { z } from "zod";
import { extractLabelValue } from "../assignment/utils/markdownUtils"; import { extractLabelValue } from "../assignments/models/utils/markdownUtils";
import { IModuleItem } from "../IModuleItem";
import { verifyDateOrThrow } from "../utils/timeUtils";
export interface LocalCoursePage extends IModuleItem { export interface LocalCoursePage extends IModuleItem {
name: string; name: string;

View File

@@ -1,11 +1,11 @@
import {
localPageMarkdownUtils,
LocalCoursePage,
} from "@/models/local/page/localCoursePage";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import path from "path"; import path from "path";
import { courseItemFileStorageService } from "./courseItemFileStorageService"; import { courseItemFileStorageService } from "../../../services/fileStorage/courseItemFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService"; import { getCoursePathByName } from "../../../services/fileStorage/globalSettingsFileStorageService";
import {
LocalCoursePage,
localPageMarkdownUtils,
} from "@/features/local/pages/localCoursePageModels";
export const pageFileStorageService = { export const pageFileStorageService = {
getPage: async (courseName: string, moduleName: string, name: string) => getPage: async (courseName: string, moduleName: string, name: string) =>

View File

@@ -1,8 +1,8 @@
import publicProcedure from "../procedures/public"; import publicProcedure from "../../../services/serverFunctions/procedures/public";
import { z } from "zod"; import { z } from "zod";
import { router } from "../trpcSetup"; import { router } from "../../../services/serverFunctions/trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService"; import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { zodLocalCoursePage } from "@/models/local/page/localCoursePage"; import { zodLocalCoursePage } from "@/features/local/pages/localCoursePageModels";
export const pageRouter = router({ export const pageRouter = router({
getPage: publicProcedure getPage: publicProcedure

View File

@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { IModuleItem } from "../IModuleItem";
import { LocalQuizQuestion, zodLocalQuizQuestion } from "./localQuizQuestion"; import { LocalQuizQuestion, zodLocalQuizQuestion } from "./localQuizQuestion";
import { quizMarkdownUtils } from "./utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "./utils/quizMarkdownUtils";
import { IModuleItem } from "@/models/local/IModuleItem";
export interface LocalQuiz extends IModuleItem { export interface LocalQuiz extends IModuleItem {
name: string; name: string;

View File

@@ -1,7 +1,4 @@
import { import { verifyDateOrThrow, verifyDateStringOrUndefined } from "@/models/local/utils/timeUtils";
verifyDateOrThrow,
verifyDateStringOrUndefined,
} from "../../utils/timeUtils";
import { LocalQuiz } from "../localQuiz"; import { LocalQuiz } from "../localQuiz";
import { quizQuestionMarkdownUtils } from "./quizQuestionMarkdownUtils"; import { quizQuestionMarkdownUtils } from "./quizQuestionMarkdownUtils";

View File

@@ -1,7 +1,7 @@
import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService"; import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { canvasModuleService } from "@/services/canvas/canvasModuleService"; import { canvasModuleService } from "@/services/canvas/canvasModuleService";
import { import {
useAddCanvasModuleMutation, useAddCanvasModuleMutation,

View File

@@ -1,6 +1,6 @@
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 "@/features/local/assignments/models/localAssignmentGroup";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } 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";

View File

@@ -1,4 +1,4 @@
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { canvasPageService } from "@/services/canvas/canvasPageService"; import { canvasPageService } from "@/services/canvas/canvasPageService";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";

View File

@@ -1,12 +1,12 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { canvasQuizService } from "@/services/canvas/canvasQuizService"; import { canvasQuizService } from "@/services/canvas/canvasQuizService";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { import {
useAddCanvasModuleMutation, useAddCanvasModuleMutation,
useCanvasModulesQuery, useCanvasModulesQuery,
} from "./canvasModuleHooks"; } from "./canvasModuleHooks";
import { canvasModuleService } from "@/services/canvas/canvasModuleService"; import { canvasModuleService } from "@/services/canvas/canvasModuleService";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export const canvasQuizKeys = { export const canvasQuizKeys = {
quizzes: (canvasCourseId: number) => quizzes: (canvasCourseId: number) =>

View File

@@ -1,15 +1,15 @@
import { LocalAssignment } from "./assignment/localAssignment"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalCoursePage } from "./page/localCoursePage"; import { LocalAssignment } from "../../features/local/assignments/models/localAssignment";
import { LocalQuiz } from "./quiz/localQuiz"; import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export type CourseItemType = "Assignment" | "Quiz" | "Page"; export type CourseItemType = "Assignment" | "Quiz" | "Page";
export type CourseItemReturnType<T extends CourseItemType> = T extends "Assignment" export type CourseItemReturnType<T extends CourseItemType> =
T extends "Assignment"
? LocalAssignment ? LocalAssignment
: T extends "Quiz" : T extends "Quiz"
? LocalQuiz ? LocalQuiz
: LocalCoursePage; : LocalCoursePage;
export const typeToFolder = { export const typeToFolder = {
Assignment: "assignments", Assignment: "assignments",
Quiz: "quizzes", Quiz: "quizzes",

View File

@@ -2,11 +2,11 @@ import { z } from "zod";
import { import {
AssignmentSubmissionType, AssignmentSubmissionType,
zodAssignmentSubmissionType, zodAssignmentSubmissionType,
} from "./assignment/assignmentSubmissionType"; } from "../../features/local/assignments/models/assignmentSubmissionType";
import { import {
LocalAssignmentGroup, LocalAssignmentGroup,
zodLocalAssignmentGroup, zodLocalAssignmentGroup,
} from "./assignment/localAssignmentGroup"; } from "../../features/local/assignments/models/localAssignmentGroup";
import { parse, stringify } from "yaml"; import { parse, stringify } from "yaml";
export interface SimpleTimeOnly { export interface SimpleTimeOnly {

View File

@@ -1,8 +1,8 @@
import { LocalAssignment } from "./assignment/localAssignment"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalAssignment } from "../../features/local/assignments/models/localAssignment";
import { IModuleItem } from "./IModuleItem"; import { IModuleItem } from "./IModuleItem";
import { LocalCoursePage } from "./page/localCoursePage";
import { LocalQuiz } from "./quiz/localQuiz";
import { getDateFromString } from "./utils/timeUtils"; import { getDateFromString } from "./utils/timeUtils";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export interface LocalModule { export interface LocalModule {
name: string; name: string;

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalAssignment } from "../assignment/localAssignment"; import { LocalAssignment } from "../../../features/local/assignments/models/localAssignment";
import { AssignmentSubmissionType } from "../assignment/assignmentSubmissionType"; import { AssignmentSubmissionType } from "../../../features/local/assignments/models/assignmentSubmissionType";
import { assignmentMarkdownSerializer } from "../assignment/utils/assignmentMarkdownSerializer"; import { assignmentMarkdownSerializer } from "../../../features/local/assignments/models/utils/assignmentMarkdownSerializer";
import { assignmentMarkdownParser } from "../assignment/utils/assignmentMarkdownParser"; import { assignmentMarkdownParser } from "../../../features/local/assignments/models/utils/assignmentMarkdownParser";
describe("AssignmentMarkdownTests", () => { describe("AssignmentMarkdownTests", () => {
it("can parse assignment settings", () => { it("can parse assignment settings", () => {

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "@/models/local/models/utils/quizMarkdownUtils";
describe("Matching Answer Error Messages", () => { describe("Matching Answer Error Messages", () => {
it("can parse matching question", () => { it("can parse matching question", () => {

View File

@@ -1,11 +1,11 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { QuestionType } from "../../quiz/localQuizQuestion"; import { QuestionType } from "../../models/localQuizQuestion";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "@/models/local/models/utils/quizMarkdownUtils";
import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; import { quizQuestionMarkdownUtils } from "@/models/local/models/utils/quizQuestionMarkdownUtils";
describe("MatchingTests", () => { describe("MatchingTests", () => {
it("can parse matching question", () => { it("can parse matching question", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -33,7 +33,7 @@ Match the following terms & definitions
}); });
it("can create markdown for matching question", () => { it("can create markdown for matching question", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -65,7 +65,7 @@ Match the following terms & definitions
}); });
it("whitespace is optional", () => { it("whitespace is optional", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -85,7 +85,7 @@ Match the following terms & definitions
}); });
it("can have distractors", () => { it("can have distractors", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -108,7 +108,7 @@ Match the following terms & definitions
}); });
it("can have distractors and be persisted", () => { it("can have distractors and be persisted", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -132,7 +132,7 @@ Match the following terms & definitions
); );
}); });
it("can escape - characters", () => { it("can escape - characters", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -149,18 +149,17 @@ Match the following terms & definitions
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name); const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0]; const firstQuestion = quiz.questions[0];
expect(firstQuestion.answers[0].text).toBe("git add --all"); expect(firstQuestion.answers[0].text).toBe("git add --all");
expect(firstQuestion.answers[0].matchedText).toBe("start tracking all files in the current directory and subdirectories"); expect(firstQuestion.answers[0].matchedText).toBe(
"start tracking all files in the current directory and subdirectories"
);
const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz);
expect(quizMarkdown).toContain( expect(quizMarkdown).toContain(
"^ git add \-\-all - start tracking all files in the current directory and subdirectories" "^ git add --all - start tracking all files in the current directory and subdirectories"
); );
}); });
}); });

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalQuiz } from "../../quiz/localQuiz"; import { LocalQuiz } from "../../models/localQuiz";
import { QuestionType } from "../../quiz/localQuizQuestion"; import { QuestionType } from "../../models/localQuizQuestion";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "@/models/local/models/utils/quizMarkdownUtils";
import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; import { quizQuestionMarkdownUtils } from "@/models/local/models/utils/quizQuestionMarkdownUtils";
describe("MultipleAnswersTests", () => { describe("MultipleAnswersTests", () => {
it("quiz markdown includes multiple answer question", () => { it("quiz markdown includes multiple answer question", () => {
@@ -41,7 +41,7 @@ oneline question
}); });
it("can parse question with multiple answers", () => { it("can parse question with multiple answers", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -79,7 +79,7 @@ Which events are triggered when the user clicks on an input field?
}); });
it("can parse question with multiple answers without a space in false answers", () => { it("can parse question with multiple answers without a space in false answers", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -105,7 +105,7 @@ Which events are triggered when the user clicks on an input field?
}); });
it("can parse question with multiple answers without a space in false answers other example", () => { it("can parse question with multiple answers without a space in false answers other example", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalQuiz } from "../../quiz/localQuiz"; import { LocalQuiz } from "../../models/localQuiz";
import { QuestionType } from "../../quiz/localQuizQuestion"; import { QuestionType } from "../../models/localQuizQuestion";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "@/models/local/models/utils/quizMarkdownUtils";
import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; import { quizQuestionMarkdownUtils } from "@/models/local/models/utils/quizQuestionMarkdownUtils";
describe("MultipleChoiceTests", () => { describe("MultipleChoiceTests", () => {
it("quiz markdown includes multiple choice question", () => { it("quiz markdown includes multiple choice question", () => {

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalQuiz } from "../../quiz/localQuiz"; import { LocalQuiz } from "../../models/localQuiz";
import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "../../models/utils/quizMarkdownUtils";
import { QuestionType } from "@/models/local/quiz/localQuizQuestion"; import { QuestionType } from "@/models/local/models/localQuizQuestion";
// Test suite for deterministic checks on LocalQuiz // Test suite for deterministic checks on LocalQuiz
describe("QuizDeterministicChecks", () => { describe("QuizDeterministicChecks", () => {

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalQuiz } from "../../quiz/localQuiz"; import { LocalQuiz } from "../../models/localQuiz";
import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; import { quizMarkdownUtils } from "../../models/utils/quizMarkdownUtils";
import { QuestionType } from "@/models/local/quiz/localQuizQuestion"; import { QuestionType } from "@/models/local/models/localQuizQuestion";
import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; import { quizQuestionMarkdownUtils } from "@/models/local/models/utils/quizQuestionMarkdownUtils";
import { markdownToHtmlNoImages } from "@/services/htmlMarkdownUtils"; import { markdownToHtmlNoImages } from "@/services/htmlMarkdownUtils";
// Test suite for QuizMarkdown // Test suite for QuizMarkdown
@@ -281,5 +281,4 @@ b) false
expect(quizHtml).toContain("<mi>x</mi>"); expect(quizHtml).toContain("<mi>x</mi>");
expect(quizHtml).not.toContain("x_2"); expect(quizHtml).not.toContain("x_2");
}); });
}); });

View File

@@ -1,12 +1,15 @@
import { getAnswers, getQuestionType } from "@/services/canvas/canvasQuizService"; import {
import { QuestionType, zodQuestionType } from "../../quiz/localQuizQuestion"; getAnswers,
import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; getQuestionType,
import { quizQuestionMarkdownUtils } from "../../quiz/utils/quizQuestionMarkdownUtils"; } from "@/services/canvas/canvasQuizService";
import { QuestionType, zodQuestionType } from "../../models/localQuizQuestion";
import { quizMarkdownUtils } from "../../models/utils/quizMarkdownUtils";
import { quizQuestionMarkdownUtils } from "../../models/utils/quizQuestionMarkdownUtils";
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
describe("TextAnswerTests", () => { describe("TextAnswerTests", () => {
it("can parse essay", () => { it("can parse essay", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -31,7 +34,7 @@ essay
}); });
it("can parse short answer", () => { it("can parse short answer", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -56,8 +59,7 @@ short answer
}); });
it("short answer to markdown is correct", () => { it("short answer to markdown is correct", () => {
const name = "Test Quiz";
const name = "Test Quiz"
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -85,8 +87,7 @@ short_answer`;
}); });
it("short_answer= to markdown is correct", () => { it("short_answer= to markdown is correct", () => {
const name = "Test Quiz";
const name = "Test Quiz"
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -118,7 +119,7 @@ short_answer=`;
}); });
it("essay question to markdown is correct", () => { it("essay question to markdown is correct", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -146,7 +147,7 @@ essay`;
}); });
it("Can parse short answer with auto graded answers", () => { it("Can parse short answer with auto graded answers", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -166,14 +167,16 @@ short_answer=
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name); const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0]; const firstQuestion = quiz.questions[0];
expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER_WITH_ANSWERS) expect(firstQuestion.questionType).toBe(
QuestionType.SHORT_ANSWER_WITH_ANSWERS
);
expect(firstQuestion.answers.length).toBe(2); expect(firstQuestion.answers.length).toBe(2);
expect(firstQuestion.answers[0].text).toBe("test"); expect(firstQuestion.answers[0].text).toBe("test");
expect(firstQuestion.answers[1].text).toBe("other"); expect(firstQuestion.answers[1].text).toBe("other");
}); });
it("Can parse short answer with auto graded answers", () => { it("Can parse short answer with auto graded answers", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -193,18 +196,22 @@ short_answer=
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name); const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0]; const firstQuestion = quiz.questions[0];
expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER_WITH_ANSWERS) expect(firstQuestion.questionType).toBe(
QuestionType.SHORT_ANSWER_WITH_ANSWERS
);
expect(firstQuestion.answers.length).toBe(2); expect(firstQuestion.answers.length).toBe(2);
expect(firstQuestion.answers[0].text).toBe("test"); expect(firstQuestion.answers[0].text).toBe("test");
expect(firstQuestion.answers[1].text).toBe("other"); expect(firstQuestion.answers[1].text).toBe("other");
}); });
it("Has short_answer= type at the same position in types and zod types", () => { it("Has short_answer= type at the same position in types and zod types", () => {
expect(Object.values(zodQuestionType.Enum)).toEqual(Object.values(QuestionType)); expect(Object.values(zodQuestionType.Enum)).toEqual(
Object.values(QuestionType)
);
}); });
it("Associates short_answer= questions with short_answer_question canvas question type", () => { it("Associates short_answer= questions with short_answer_question canvas question type", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -228,7 +235,7 @@ short_answer=
}); });
it("Includes answer_text in answers sent to canvas", () => { it("Includes answer_text in answers sent to canvas", () => {
const name = "Test Quiz" const name = "Test Quiz";
const rawMarkdownQuiz = ` const rawMarkdownQuiz = `
ShuffleAnswers: true ShuffleAnswers: true
OneQuestionAtATime: false OneQuestionAtATime: false
@@ -257,16 +264,15 @@ short_answer=
endDate: "", endDate: "",
defaultDueTime: { defaultDueTime: {
hour: 0, hour: 0,
minute: 0 minute: 0,
}, },
defaultAssignmentSubmissionTypes: [], defaultAssignmentSubmissionTypes: [],
defaultFileUploadTypes: [], defaultFileUploadTypes: [],
holidays: [], holidays: [],
assets: [] assets: [],
}) });
expect(answers).toHaveLength(2); expect(answers).toHaveLength(2);
const firstAnswer = answers[0]; const firstAnswer = answers[0];
expect(firstAnswer).toHaveProperty("answer_text"); expect(firstAnswer).toHaveProperty("answer_text");
}); });
}); });

View File

@@ -1,6 +1,9 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { RubricItem, rubricItemIsExtraCredit } from "../assignment/rubricItem"; import {
import { assignmentMarkdownParser } from "../assignment/utils/assignmentMarkdownParser"; RubricItem,
rubricItemIsExtraCredit,
} from "../../../features/local/assignments/models/rubricItem";
import { assignmentMarkdownParser } from "../../../features/local/assignments/models/utils/assignmentMarkdownParser";
describe("RubricMarkdownTests", () => { describe("RubricMarkdownTests", () => {
it("can parse one item", () => { it("can parse one item", () => {

View File

@@ -1,12 +1,12 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { LocalAssignment } from "../assignment/localAssignment"; import { LocalAssignment } from "../../../features/local/assignments/models/localAssignment";
import { import {
prepAssignmentForNewSemester, prepAssignmentForNewSemester,
prepLectureForNewSemester, prepLectureForNewSemester,
prepPageForNewSemester, prepPageForNewSemester,
prepQuizForNewSemester, prepQuizForNewSemester,
} from "../utils/semesterTransferUtils"; } from "../utils/semesterTransferUtils";
import { LocalQuiz } from "../quiz/localQuiz"; import { LocalQuiz } from "../models/localQuiz";
import { LocalCoursePage } from "../page/localCoursePage"; import { LocalCoursePage } from "../page/localCoursePage";
import { Lecture } from "../lecture"; import { Lecture } from "../lecture";

View File

@@ -1,12 +1,8 @@
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalAssignment } from "../assignment/localAssignment"; import { LocalAssignment } from "../../../features/local/assignments/models/localAssignment";
import { Lecture } from "../lecture"; import { Lecture } from "../lecture";
import { LocalCoursePage } from "../page/localCoursePage"; import { dateToMarkdownString, getDateFromStringOrThrow } from "./timeUtils";
import { LocalQuiz } from "../quiz/localQuiz"; import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import {
dateToMarkdownString,
getDateFromStringOrThrow,
} from "./timeUtils";
export const prepAssignmentForNewSemester = ( export const prepAssignmentForNewSemester = (
assignment: LocalAssignment, assignment: LocalAssignment,

View File

@@ -1,16 +1,14 @@
import { canvasApi, paginatedRequest } from "./canvasServiceUtils"; import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
import { axiosClient } from "../axiosUtils"; import { axiosClient } from "../axiosUtils";
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup"; import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup"; import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import { rateLimitAwareDelete } from "./canvasWebRequestor"; import { rateLimitAwareDelete } from "./canvasWebRequestor";
export const canvasAssignmentGroupService = { export const canvasAssignmentGroupService = {
async getAll(courseId: number): Promise<CanvasAssignmentGroup[]> { async getAll(courseId: number): Promise<CanvasAssignmentGroup[]> {
console.log("Requesting assignment groups"); console.log("Requesting assignment groups");
const url = `${canvasApi}/courses/${courseId}/assignment_groups`; const url = `${canvasApi}/courses/${courseId}/assignment_groups`;
const assignmentGroups = await paginatedRequest< const assignmentGroups = await paginatedRequest<CanvasAssignmentGroup[]>({
CanvasAssignmentGroup[]
>({
url, url,
}); });
return assignmentGroups.flatMap((groupList) => groupList); return assignmentGroups.flatMap((groupList) => groupList);
@@ -40,7 +38,9 @@ export const canvasAssignmentGroupService = {
canvasCourseId: number, canvasCourseId: number,
localAssignmentGroup: LocalAssignmentGroup localAssignmentGroup: LocalAssignmentGroup
): Promise<void> { ): Promise<void> {
console.log(`Updating assignment group: ${localAssignmentGroup.name}, ${localAssignmentGroup.canvasId}`); 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

@@ -1,10 +1,10 @@
import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment"; import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment";
import { canvasApi, paginatedRequest } from "./canvasServiceUtils"; import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { axiosClient } from "../axiosUtils"; import { axiosClient } from "../axiosUtils";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils"; import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { CanvasRubricCreationResponse } from "@/models/canvas/assignments/canvasRubricCreationResponse"; import { CanvasRubricCreationResponse } from "@/models/canvas/assignments/canvasRubricCreationResponse";
import { assignmentPoints } from "@/models/local/assignment/utils/assignmentPointsUtils"; import { assignmentPoints } from "@/features/local/assignments/models/utils/assignmentPointsUtils";
import { getDateFromString } from "@/models/local/utils/timeUtils"; import { getDateFromString } from "@/models/local/utils/timeUtils";
import { getRubricCriterion } from "./canvasRubricUtils"; import { getRubricCriterion } from "./canvasRubricUtils";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } from "@/models/local/localCourseSettings";

View File

@@ -1,5 +1,5 @@
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel"; import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { canvasApi, paginatedRequest } from "./canvasServiceUtils"; import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils"; import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { axiosClient } from "../axiosUtils"; import { axiosClient } from "../axiosUtils";

View File

@@ -1,17 +1,14 @@
import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel"; import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel";
import { axiosClient } from "../axiosUtils"; import { axiosClient } from "../axiosUtils";
import { canvasApi, paginatedRequest } from "./canvasServiceUtils"; import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils"; import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils"; import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import { canvasAssignmentService } from "./canvasAssignmentService"; import { canvasAssignmentService } from "./canvasAssignmentService";
import {
LocalQuizQuestion,
QuestionType,
} from "@/models/local/quiz/localQuizQuestion";
import { CanvasQuizQuestion } from "@/models/canvas/quizzes/canvasQuizQuestionModel"; import { CanvasQuizQuestion } from "@/models/canvas/quizzes/canvasQuizQuestionModel";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { escapeMatchingText } from "../utils/questionHtmlUtils"; import { escapeMatchingText } from "../utils/questionHtmlUtils";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { LocalQuizQuestion, QuestionType } from "@/features/local/quizzes/models/localQuizQuestion";
export const getAnswers = ( export const getAnswers = (
question: LocalQuizQuestion, question: LocalQuizQuestion,

View File

@@ -1,4 +1,4 @@
import { RubricItem } from "@/models/local/assignment/rubricItem"; import { RubricItem } from "@/features/local/assignments/models/rubricItem";
export const getRubricCriterion = (rubric: RubricItem[]) => { export const getRubricCriterion = (rubric: RubricItem[]) => {
const criterion = rubric const criterion = rubric
@@ -17,6 +17,5 @@ export const getRubricCriterion = (rubric: RubricItem[]) => {
}; };
}, {} as { [key: number]: { description: string; points: number; ratings: { [key: number]: { description: string; points: number } } } }); }, {} as { [key: number]: { description: string; points: number; ratings: { [key: number]: { description: string; points: number } } } });
return criterion return criterion;
};
}

View File

@@ -1,21 +1,21 @@
import { RubricItem } from "@/models/local/assignment/rubricItem"; import { RubricItem } from "@/features/local/assignments/models/rubricItem";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { getRubricCriterion } from "./canvasRubricUtils"; import { getRubricCriterion } from "./canvasRubricUtils";
import { assignmentPoints } from "@/models/local/assignment/utils/assignmentPointsUtils"; import { assignmentPoints } from "@/features/local/assignments/models/utils/assignmentPointsUtils";
describe("can prepare rubric for canvas", () => { describe("can prepare rubric for canvas", () => {
it("can parse normal rubric into criterion", () => { it("can parse normal rubric into criterion", () => {
const rubric: RubricItem[] = [ const rubric: RubricItem[] = [
{ {
label: "first", label: "first",
points: 1 points: 1,
}, },
{ {
label: "second", label: "second",
points: 2 points: 2,
}, },
] ];
const criterion = getRubricCriterion(rubric) const criterion = getRubricCriterion(rubric);
expect(criterion).toStrictEqual({ expect(criterion).toStrictEqual({
0: { 0: {
@@ -24,7 +24,7 @@ describe("can prepare rubric for canvas", () =>{
ratings: { ratings: {
0: { description: "Full Marks", points: 1 }, 0: { description: "Full Marks", points: 1 },
1: { description: "No Marks", points: 0 }, 1: { description: "No Marks", points: 0 },
} },
}, },
1: { 1: {
description: "second", description: "second",
@@ -32,24 +32,23 @@ describe("can prepare rubric for canvas", () =>{
ratings: { ratings: {
0: { description: "Full Marks", points: 2 }, 0: { description: "Full Marks", points: 2 },
1: { description: "No Marks", points: 0 }, 1: { description: "No Marks", points: 0 },
} },
} },
}) });
}) });
it("can parse negative rubric into criterion", () => { it("can parse negative rubric into criterion", () => {
const rubric: RubricItem[] = [ const rubric: RubricItem[] = [
{ {
label: "first", label: "first",
points: 1 points: 1,
}, },
{ {
label: "second", label: "second",
points: -2 points: -2,
}, },
] ];
const criterion = getRubricCriterion(rubric) const criterion = getRubricCriterion(rubric);
expect(criterion).toStrictEqual({ expect(criterion).toStrictEqual({
0: { 0: {
@@ -58,7 +57,7 @@ describe("can prepare rubric for canvas", () =>{
ratings: { ratings: {
0: { description: "Full Marks", points: 1 }, 0: { description: "Full Marks", points: 1 },
1: { description: "No Marks", points: 0 }, 1: { description: "No Marks", points: 0 },
} },
}, },
1: { 1: {
description: "second", description: "second",
@@ -66,28 +65,27 @@ describe("can prepare rubric for canvas", () =>{
ratings: { ratings: {
0: { description: "Full Marks", points: -2 }, 0: { description: "Full Marks", points: -2 },
1: { description: "No Marks", points: 0 }, 1: { description: "No Marks", points: 0 },
} },
} },
}) });
}) });
it("negative rubric items do not contribute to the total", () => { it("negative rubric items do not contribute to the total", () => {
const rubric: RubricItem[] = [ const rubric: RubricItem[] = [
{ {
label: "first", label: "first",
points: 1 points: 1,
}, },
{ {
label: "second", label: "second",
points: -2 points: -2,
}, },
{ {
label: "second", label: "second",
points: 3 points: 3,
}, },
] ];
const points = assignmentPoints(rubric) const points = assignmentPoints(rubric);
expect(points).toBe(4) expect(points).toBe(4);
}) });
}) });

View File

@@ -1,8 +1,8 @@
import { import {
localAssignmentMarkdown, localAssignmentMarkdown,
LocalAssignment, LocalAssignment,
} from "@/models/local/assignment/localAssignment"; } from "@/features/local/assignments/models/localAssignment";
import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/assignmentMarkdownSerializer"; import { assignmentMarkdownSerializer } from "@/features/local/assignments/models/utils/assignmentMarkdownSerializer";
import path from "path"; import path from "path";
import { directoryOrFileExists } from "./utils/fileSystemUtils"; import { directoryOrFileExists } from "./utils/fileSystemUtils";
import { promises as fs } from "fs"; import { promises as fs } from "fs";

View File

@@ -4,23 +4,20 @@ import fs from "fs/promises";
import { import {
LocalAssignment, LocalAssignment,
localAssignmentMarkdown, localAssignmentMarkdown,
} from "@/models/local/assignment/localAssignment"; } from "@/features/local/assignments/models/localAssignment";
import { import { assignmentMarkdownSerializer } from "@/features/local/assignments/models/utils/assignmentMarkdownSerializer";
LocalQuiz,
localQuizMarkdownUtils,
} from "@/models/local/quiz/localQuiz";
import {
LocalCoursePage,
localPageMarkdownUtils,
} from "@/models/local/page/localCoursePage";
import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/assignmentMarkdownSerializer";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
import { import {
CourseItemReturnType, CourseItemReturnType,
CourseItemType, CourseItemType,
typeToFolder, typeToFolder,
} from "@/models/local/courseItemTypes"; } from "@/models/local/courseItemTypes";
import { getCoursePathByName } from "./globalSettingsFileStorageService"; import { getCoursePathByName } from "./globalSettingsFileStorageService";
import {
localPageMarkdownUtils,
LocalCoursePage,
} from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz, localQuizMarkdownUtils } from "@/features/local/quizzes/models/localQuiz";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";
const getItemFileNames = async ( const getItemFileNames = async (
courseName: string, courseName: string,

View File

@@ -3,7 +3,7 @@ import path from "path";
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils"; import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
import { assignmentsFileStorageService } from "./assignmentsFileStorageService"; import { assignmentsFileStorageService } from "./assignmentsFileStorageService";
import { quizFileStorageService } from "./quizFileStorageService"; import { quizFileStorageService } from "./quizFileStorageService";
import { pageFileStorageService } from "./pageFileStorageService"; import { pageFileStorageService } from "../../features/local/pages/pageFileStorageService";
import { moduleFileStorageService } from "./moduleFileStorageService"; import { moduleFileStorageService } from "./moduleFileStorageService";
import { settingsFileStorageService } from "./settingsFileStorageService"; import { settingsFileStorageService } from "./settingsFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService"; import { getCoursePathByName } from "./globalSettingsFileStorageService";

View File

@@ -46,11 +46,4 @@ export const updateGlobalSettings = async (globalSettings: GlobalSettings) => {
zodGlobalSettings.parse(globalSettings) zodGlobalSettings.parse(globalSettings)
); );
await fs.writeFile(SETTINGS_FILE_PATH, globalSettingsString, "utf-8"); await fs.writeFile(SETTINGS_FILE_PATH, globalSettingsString, "utf-8");
// await Promise.all(
// globalSettings.courses.map(async (course) => {
// const coursePath = await getCoursePathByName(course.name);
// await fs.mkdir(coursePath, { recursive: true });
// })
// );
}; };

View File

@@ -1,9 +1,9 @@
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
import path from "path"; import path from "path";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import { courseItemFileStorageService } from "./courseItemFileStorageService"; import { courseItemFileStorageService } from "./courseItemFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService"; import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";
export const quizFileStorageService = { export const quizFileStorageService = {
getQuiz: async (courseName: string, moduleName: string, quizName: string) => getQuiz: async (courseName: string, moduleName: string, quizName: string) =>

View File

@@ -5,7 +5,7 @@ import {
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import path from "path"; import path from "path";
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils"; import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType"; import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import { import {
getCoursePathByName, getCoursePathByName,
getGlobalSettings, getGlobalSettings,

View File

@@ -1,5 +1,5 @@
import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils"; import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils";
import { extractLabelValue } from "@/models/local/assignment/utils/markdownUtils"; import { extractLabelValue } from "@/features/local/assignments/models/utils/markdownUtils";
import { Lecture } from "@/models/local/lecture"; import { Lecture } from "@/models/local/lecture";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils"; import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";

View File

@@ -1,12 +1,12 @@
import { createTrpcContext } from "../context"; import { createTrpcContext } from "../context";
import { createCallerFactory, router } from "../trpcSetup"; import { createCallerFactory, router } from "../trpcSetup";
import { assignmentRouter } from "./assignmentRouter"; import { assignmentRouter } from "../../../features/local/assignments/assignmentRouter";
import { canvasFileRouter } from "./canvasFileRouter"; import { canvasFileRouter } from "./canvasFileRouter";
import { directoriesRouter } from "./directoriesRouter"; import { directoriesRouter } from "./directoriesRouter";
import { globalSettingsRouter } from "./globalSettingsRouter"; import { globalSettingsRouter } from "./globalSettingsRouter";
import { lectureRouter } from "./lectureRouter"; import { lectureRouter } from "./lectureRouter";
import { moduleRouter } from "./moduleRouter"; import { moduleRouter } from "./moduleRouter";
import { pageRouter } from "./pageRouter"; import { pageRouter } from "../../../features/local/pages/pageRouter";
import { quizRouter } from "./quizRouter"; import { quizRouter } from "./quizRouter";
import { settingsRouter } from "./settingsRouter"; import { settingsRouter } from "./settingsRouter";

View File

@@ -2,7 +2,7 @@ import publicProcedure from "../procedures/public";
import { z } from "zod"; import { z } from "zod";
import { router } from "../trpcSetup"; import { router } from "../trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService"; import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { zodLocalQuiz } from "@/models/local/quiz/localQuiz"; import { zodLocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export const quizRouter = router({ export const quizRouter = router({
getQuiz: publicProcedure getQuiz: publicProcedure