more configs for default types

This commit is contained in:
2024-10-01 13:42:59 -06:00
parent f8c4978319
commit c128966255
12 changed files with 222 additions and 27 deletions

View File

@@ -30,24 +30,32 @@ function createCalendarMonth(year: number, month: number): CalendarMonthModel {
let currentDay = 1;
const firstDayOfMonth = new Date(year, month - 1, 1).getDay();
const daysByWeek = Array.from({ length: weeksNumber }).map((_, weekIndex) =>
Array.from({ length: 7 }).map((_, dayIndex) => {
if (weekIndex === 0 && dayIndex < firstDayOfMonth) {
return dateToMarkdownString(
new Date(year, month - 1, dayIndex - firstDayOfMonth + 1, 12, 0, 0)
);
} else if (currentDay <= daysInMonth) {
return dateToMarkdownString(
new Date(year, month - 1, currentDay++, 12, 0, 0)
);
} else {
currentDay++;
return dateToMarkdownString(
new Date(year, month, currentDay - daysInMonth - 1, 12, 0, 0)
);
}
})
);
const daysByWeek = Array.from({ length: weeksNumber })
.map((_, weekIndex) =>
Array.from({ length: 7 }).map((_, dayIndex) => {
if (weekIndex === 0 && dayIndex < firstDayOfMonth) {
return dateToMarkdownString(
new Date(year, month - 1, dayIndex - firstDayOfMonth + 1, 12, 0, 0)
);
} else if (currentDay <= daysInMonth) {
return dateToMarkdownString(
new Date(year, month - 1, currentDay++, 12, 0, 0)
);
} else {
currentDay++;
return dateToMarkdownString(
new Date(year, month, currentDay - daysInMonth - 1, 12, 0, 0)
);
}
})
)
.filter((week) => {
const lastDate = getDateFromStringOrThrow(
week.at(-1)!,
"filtering out last week of month"
);
return lastDate.getMonth() <= month - 1;
});
const weeks = daysByWeek.map((week) =>
week.map((day) =>

View File

@@ -33,7 +33,6 @@ export default function EditAssignment({
const [assignmentText, setAssignmentText] = useState(
localAssignmentMarkdown.toMarkdown(assignment)
);
console.log("assignment text render");
const [error, setError] = useState("");
const [showHelp, setShowHelp] = useState(false);

View File

@@ -22,6 +22,12 @@ export default function QuizPreview({
<div className="text-end">Name</div>
<div>{quiz.name}</div>
</div>
<div className="columns-2">
<div className="text-end">Points</div>
<div>
{quiz.questions.reduce((sum, question) => sum + question.points, 0)}
</div>
</div>
<div className="columns-2">
<div className="text-end">Due Date</div>
<div>{quiz.dueAt}</div>
@@ -46,9 +52,12 @@ export default function QuizPreview({
<div className="text-end">Assignment Group Name</div>
<div>{quiz.localAssignmentGroupName}</div>
</div>
<div className="p-3" style={{ whiteSpace: "pre-wrap" }}>
{quiz.description}
</div>
<div
className="p-3 markdownPreview"
dangerouslySetInnerHTML={{
__html: markdownToHTMLSafe(quiz.description),
}}
></div>
<div className="p-3 rounded-md bg-slate-950 m-5 flex flex-col gap-3">
{quiz.questions.map((question, i) => (
<QuizQuestionPreview key={i} question={question} />

View File

@@ -70,7 +70,7 @@ export default function AssignmentGroupManagement() {
<button
className="btn-danger"
onClick={() => {
setAssignmentGroups((oldGroups) => oldGroups.slice(1));
setAssignmentGroups((oldGroups) => oldGroups.slice(0, -1));
}}
>
Remove Assignment Group

View File

@@ -0,0 +1,65 @@
"use client";
import TextInput from "@/components/form/TextInput";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
import { useState, useEffect } from "react";
export default function DefaultFileUploadTypes() {
const { data: settings } = useLocalCourseSettingsQuery();
const [defaultFileUploadTypes, setDefaultFileUploadTypes] = useState<
string[]
>(settings.defaultFileUploadTypes);
const updateSettings = useUpdateLocalCourseSettingsMutation();
useEffect(() => {
const id = setTimeout(() => {
if (
JSON.stringify(settings.defaultFileUploadTypes) !==
JSON.stringify(defaultFileUploadTypes)
) {
updateSettings.mutate({
...settings,
defaultFileUploadTypes: defaultFileUploadTypes,
});
}
}, 500);
return () => clearTimeout(id);
}, [defaultFileUploadTypes, settings, updateSettings]);
return (
<div className="border w-fit p-3 m-3 rounded-md">
<div className="text-center">Default File Upload Types</div>
{defaultFileUploadTypes.map((type, index) => (
<div key={index} className="flex flex-row gap-3">
<TextInput
value={type}
setValue={(newValue) =>
setDefaultFileUploadTypes((oldTypes) =>
oldTypes.map((t, i) => (i === index ? newValue : t))
)
}
label={"Default Type " + index}
/>
</div>
))}
<div className="flex gap-3 mt-3">
<button
className="btn-danger"
onClick={() => {
setDefaultFileUploadTypes((old) => old.slice(0, -1));
}}
>
Remove Default File Upload Type
</button>
<button
onClick={() => setDefaultFileUploadTypes((old) => [...old, ""])}
>
Add Default File Upload Type
</button>
</div>
</div>
);
}

View File

@@ -0,0 +1,76 @@
"use client";
import SelectInput from "@/components/form/SelectInput";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
import {
AssignmentSubmissionType,
AssignmentSubmissionTypeList,
} from "@/models/local/assignment/assignmentSubmissionType";
import React, { useEffect, useState } from "react";
export default function SubmissionDefaults() {
const { data: settings } = useLocalCourseSettingsQuery();
const [defaultSubmissionTypes, setDefaultSubmissionTypes] = useState<
AssignmentSubmissionType[]
>(settings.defaultAssignmentSubmissionTypes);
const updateSettings = useUpdateLocalCourseSettingsMutation();
useEffect(() => {
if (
JSON.stringify(settings.defaultAssignmentSubmissionTypes) !==
JSON.stringify(defaultSubmissionTypes)
) {
updateSettings.mutate({
...settings,
defaultAssignmentSubmissionTypes: defaultSubmissionTypes,
});
}
}, [defaultSubmissionTypes, settings, updateSettings]);
return (
<div className="border w-fit p-3 m-3 rounded-md">
<div className="text-center">Default Assignment Submission Type</div>
{defaultSubmissionTypes.map((type, index) => (
<div key={index} className="flex flex-row gap-3">
<SelectInput
value={type}
setValue={(newType) => {
if (newType)
setDefaultSubmissionTypes((oldTypes) =>
oldTypes.map((t, i) => (i === index ? newType : t))
);
}}
label={""}
options={AssignmentSubmissionTypeList}
getOptionName={(t) => t}
/>
</div>
))}
<div className="flex gap-3 mt-3">
<button
className="btn-danger"
onClick={() => {
setDefaultSubmissionTypes((old) => old.slice(0, -1));
}}
>
Remove Default Type
</button>
<button
onClick={() =>
setDefaultSubmissionTypes((old) => [
...old,
AssignmentSubmissionType.NONE,
])
}
>
Add Default Type
</button>
</div>
</div>
);
}

View File

@@ -5,6 +5,8 @@ import SettingsHeader from "./SettingsHeader";
import DefaultDueTime from "./DefaultDueTime";
import DaysOfWeekSettings from "./DaysOfWeekSettings";
import AssignmentGroupManagement from "./AssignmentGroupManagement";
import SubmissionDefaults from "./SubmissionDefaults";
import DefaultFileUploadTypes from "./DefaultFileUploadTypes";
export default function page() {
return (
@@ -13,6 +15,8 @@ export default function page() {
<SettingsHeader />
<DaysOfWeekSettings />
<StartAndEndDate />
<SubmissionDefaults />
<DefaultFileUploadTypes />
<DefaultDueTime />
<AssignmentGroupManagement />
</div>

View File

@@ -12,6 +12,7 @@ import {
import { useEmptyDirectoriesQuery } from "@/hooks/localCourse/storageDirectoryHooks";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType";
import { DayOfWeek } from "@/models/local/localCourse";
import { getCourseUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation";
@@ -89,6 +90,10 @@ export default function NewCourseForm() {
startDate: selectedTerm.start_at ?? "",
endDate: selectedTerm.end_at ?? "",
defaultDueTime: { hour: 23, minute: 59 },
defaultAssignmentSubmissionTypes: [
AssignmentSubmissionType.ONLINE_TEXT_ENTRY,
AssignmentSubmissionType.ONLINE_UPLOAD,
],
},
})
.then(() => {

View File

@@ -17,8 +17,8 @@ export function DayOfWeekInput({
key={day}
className={
hasDay
? "bg-blue-300 text-blue-950 border-blue-500 border"
: "bg-slate-900 border-blue-900 border "
? ""
: "unstyled btn-outline "
}
onClick={() => updateSettings(day)}
>

View File

@@ -6,3 +6,12 @@ export enum AssignmentSubmissionType {
ONLINE_URL = "online_url",
NONE = "none",
}
export const AssignmentSubmissionTypeList: AssignmentSubmissionType[] = [
AssignmentSubmissionType.ONLINE_TEXT_ENTRY,
AssignmentSubmissionType.ONLINE_UPLOAD,
AssignmentSubmissionType.ONLINE_QUIZ,
AssignmentSubmissionType.DISCUSSION_TOPIC,
AssignmentSubmissionType.ONLINE_URL,
AssignmentSubmissionType.NONE,
] as const;

View File

@@ -1,3 +1,4 @@
import { AssignmentSubmissionType } from "./assignment/assignmentSubmissionType";
import { LocalAssignmentGroup } from "./assignment/localAssignmentGroup";
import { LocalModule } from "./localModules";
import { parse, stringify } from "yaml";
@@ -20,6 +21,8 @@ export interface LocalCourseSettings {
startDate: string;
endDate: string;
defaultDueTime: SimpleTimeOnly;
defaultAssignmentSubmissionTypes: AssignmentSubmissionType[];
defaultFileUploadTypes: string[];
}
export enum DayOfWeek {

View File

@@ -9,6 +9,7 @@ import {
directoryOrFileExists,
getCourseNames,
} from "./utils/fileSystemUtils";
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType";
const getCourseSettings = async (
courseName: string
@@ -22,7 +23,24 @@ const getCourseSettings = async (
}
const settingsString = await fs.readFile(settingsPath, "utf-8");
const settings = localCourseYamlUtils.parseSettingYaml(settingsString);
const settingsFromFile =
localCourseYamlUtils.parseSettingYaml(settingsString);
const defaultSubmissionType = [
AssignmentSubmissionType.ONLINE_TEXT_ENTRY,
AssignmentSubmissionType.ONLINE_UPLOAD,
];
const defaultFileUploadTypes = ["pdf", "jpg", "jpeg", "pdf"];
const settings: LocalCourseSettings = {
...settingsFromFile,
defaultAssignmentSubmissionTypes:
settingsFromFile.defaultAssignmentSubmissionTypes ||
defaultSubmissionType,
defaultFileUploadTypes:
settingsFromFile.defaultFileUploadTypes || defaultFileUploadTypes,
};
const folderName = path.basename(courseDirectory);
return { ...settings, name: folderName };
@@ -54,4 +72,3 @@ export const settingsFileStorageService = {
await fs.writeFile(settingsPath, settingsMarkdown);
},
};