mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-26 07:38:33 -06:00
more layout and cleanup
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||
import CourseContextProvider from "./context/CourseContextProvider";
|
||||
import { Suspense } from "react";
|
||||
import { getQueryClient } from "@/app/providersQueryClientUtils";
|
||||
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
|
||||
import { hydrateCanvasCourse } from "@/hooks/hookHydration";
|
||||
|
||||
export default async function CourseLayout({
|
||||
children,
|
||||
@@ -13,11 +17,19 @@ export default async function CourseLayout({
|
||||
console.log("cannot load course that is .js.map " + decodedCourseName);
|
||||
return <div></div>;
|
||||
}
|
||||
const settings = await fileStorageService.settings.getCourseSettings(
|
||||
decodedCourseName
|
||||
);
|
||||
const queryClient = getQueryClient();
|
||||
await hydrateCanvasCourse(settings.canvasId, queryClient);
|
||||
const dehydratedState = dehydrate(queryClient);
|
||||
return (
|
||||
<Suspense>
|
||||
<CourseContextProvider localCourseName={decodedCourseName}>
|
||||
{children}
|
||||
</CourseContextProvider>
|
||||
<HydrationBoundary state={dehydratedState}>
|
||||
<CourseContextProvider localCourseName={decodedCourseName}>
|
||||
{children}
|
||||
</CourseContextProvider>
|
||||
</HydrationBoundary>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function AssignmentPreview({
|
||||
assignment: LocalAssignment;
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<div className="h-full overflow-y-auto">
|
||||
<section>
|
||||
<div className="flex">
|
||||
<div className="flex-1 text-end pe-3">Due Date</div>
|
||||
|
||||
@@ -21,6 +21,8 @@ import { Spinner } from "@/components/Spinner";
|
||||
import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
|
||||
import ClientOnly from "@/components/ClientOnly";
|
||||
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
|
||||
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType";
|
||||
import { LocalCourseSettings } from "@/models/local/localCourse";
|
||||
|
||||
export default function EditAssignment({
|
||||
moduleName,
|
||||
@@ -29,6 +31,7 @@ export default function EditAssignment({
|
||||
assignmentName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const { data: settings } = useLocalCourseSettingsQuery();
|
||||
const { data: assignment } = useAssignmentQuery(moduleName, assignmentName);
|
||||
const updateAssignment = useUpdateAssignmentMutation();
|
||||
|
||||
@@ -36,6 +39,7 @@ export default function EditAssignment({
|
||||
localAssignmentMarkdown.toMarkdown(assignment)
|
||||
);
|
||||
const [error, setError] = useState("");
|
||||
const [showHelp, setShowHelp] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const delay = 500;
|
||||
@@ -72,14 +76,23 @@ export default function EditAssignment({
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="columns-2 min-h-0 flex-1">
|
||||
<div className="h-full flex flex-col align-middle px-1">
|
||||
<div className={"min-h-96 flex flex-row w-full"}>
|
||||
{showHelp && (
|
||||
<pre className=" max-w-96">
|
||||
<code>{getHelpString(settings)}</code>
|
||||
</pre>
|
||||
)}
|
||||
<div className="flex-1 h-full">
|
||||
<MonacoEditor value={assignmentText} onChange={setAssignmentText} />
|
||||
</div>
|
||||
<div className="h-full">
|
||||
<div className="flex-1 h-full">
|
||||
<div className="text-red-300">{error && error}</div>
|
||||
|
||||
<div className="px-3 h-full">
|
||||
|
||||
<AssignmentPreview assignment={assignment} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ClientOnly>
|
||||
@@ -87,6 +100,7 @@ export default function EditAssignment({
|
||||
<AssignmentButtons
|
||||
moduleName={moduleName}
|
||||
assignmentName={assignmentName}
|
||||
toggleHelp={() => setShowHelp((h) => !h)}
|
||||
/>
|
||||
</SuspenseAndErrorHandling>
|
||||
</ClientOnly>
|
||||
@@ -94,12 +108,30 @@ export default function EditAssignment({
|
||||
);
|
||||
}
|
||||
|
||||
function getHelpString(settings: LocalCourseSettings) {
|
||||
const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- ");
|
||||
const helpString = `SubmissionTypes:
|
||||
- ${AssignmentSubmissionType.ONLINE_TEXT_ENTRY}
|
||||
- ${AssignmentSubmissionType.ONLINE_UPLOAD}
|
||||
- ${AssignmentSubmissionType.DISCUSSION_TOPIC}
|
||||
AllowedFileUploadExtensions:
|
||||
- pdf
|
||||
- jpg
|
||||
- jpeg
|
||||
- png
|
||||
Assignment Group Names:
|
||||
- ${groupNames}`;
|
||||
return helpString;
|
||||
}
|
||||
|
||||
function AssignmentButtons({
|
||||
moduleName,
|
||||
assignmentName,
|
||||
toggleHelp,
|
||||
}: {
|
||||
assignmentName: string;
|
||||
moduleName: string;
|
||||
toggleHelp: () => void;
|
||||
}) {
|
||||
const { courseName } = useCourseContext();
|
||||
const { data: settings } = useLocalCourseSettingsQuery();
|
||||
@@ -113,61 +145,66 @@ function AssignmentButtons({
|
||||
(a) => a.name === assignmentName
|
||||
);
|
||||
return (
|
||||
<div className="p-5 flex flex-row justify-end gap-3">
|
||||
{(addToCanvas.isPending ||
|
||||
deleteFromCanvas.isPending ||
|
||||
updateAssignment.isPending) && <Spinner />}
|
||||
{assignmentInCanvas && !assignmentInCanvas.published && (
|
||||
<div className="text-rose-300 my-auto">Not Published</div>
|
||||
)}
|
||||
{!assignmentInCanvas && (
|
||||
<button
|
||||
disabled={addToCanvas.isPending}
|
||||
onClick={() => addToCanvas.mutate(assignment)}
|
||||
>
|
||||
Add to canvas
|
||||
</button>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<a
|
||||
className="btn"
|
||||
target="_blank"
|
||||
href={`${baseCanvasUrl}/courses/${settings.canvasId}/assignments/${assignmentInCanvas.id}`}
|
||||
>
|
||||
View in Canvas
|
||||
</a>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<button
|
||||
className=""
|
||||
disabled={deleteFromCanvas.isPending}
|
||||
onClick={() =>
|
||||
updateAssignment.mutate({
|
||||
canvasAssignmentId: assignmentInCanvas.id,
|
||||
assignment,
|
||||
})
|
||||
}
|
||||
>
|
||||
Update in Canvas
|
||||
</button>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<button
|
||||
className="btn-danger"
|
||||
disabled={deleteFromCanvas.isPending}
|
||||
onClick={() =>
|
||||
deleteFromCanvas.mutate({
|
||||
canvasAssignmentId: assignmentInCanvas.id,
|
||||
assignmentName: assignment.name,
|
||||
})
|
||||
}
|
||||
>
|
||||
Delete from Canvas
|
||||
</button>
|
||||
)}
|
||||
<Link className="btn" href={getCourseUrl(courseName)} shallow={true}>
|
||||
Go Back
|
||||
</Link>
|
||||
<div className="p-5 flex flex-row justify-between gap-3">
|
||||
<div>
|
||||
<button onClick={toggleHelp}>Toggle Help</button>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 justify-end">
|
||||
{(addToCanvas.isPending ||
|
||||
deleteFromCanvas.isPending ||
|
||||
updateAssignment.isPending) && <Spinner />}
|
||||
{assignmentInCanvas && !assignmentInCanvas.published && (
|
||||
<div className="text-rose-300 my-auto">Not Published</div>
|
||||
)}
|
||||
{!assignmentInCanvas && (
|
||||
<button
|
||||
disabled={addToCanvas.isPending}
|
||||
onClick={() => addToCanvas.mutate(assignment)}
|
||||
>
|
||||
Add to canvas
|
||||
</button>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<a
|
||||
className="btn"
|
||||
target="_blank"
|
||||
href={`${baseCanvasUrl}/courses/${settings.canvasId}/assignments/${assignmentInCanvas.id}`}
|
||||
>
|
||||
View in Canvas
|
||||
</a>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<button
|
||||
className=""
|
||||
disabled={deleteFromCanvas.isPending}
|
||||
onClick={() =>
|
||||
updateAssignment.mutate({
|
||||
canvasAssignmentId: assignmentInCanvas.id,
|
||||
assignment,
|
||||
})
|
||||
}
|
||||
>
|
||||
Update in Canvas
|
||||
</button>
|
||||
)}
|
||||
{assignmentInCanvas && (
|
||||
<button
|
||||
className="btn-danger"
|
||||
disabled={deleteFromCanvas.isPending}
|
||||
onClick={() =>
|
||||
deleteFromCanvas.mutate({
|
||||
canvasAssignmentId: assignmentInCanvas.id,
|
||||
assignmentName: assignment.name,
|
||||
})
|
||||
}
|
||||
>
|
||||
Delete from Canvas
|
||||
</button>
|
||||
)}
|
||||
<Link className="btn" href={getCourseUrl(courseName)} shallow={true}>
|
||||
Go Back
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user