working on settings

This commit is contained in:
2024-09-11 21:33:35 -06:00
parent f42f631fad
commit 32b59b3975
7 changed files with 131 additions and 34 deletions

View File

@@ -1,17 +1,48 @@
import { DayOfWeekInput } from "@/components/form/DayOfWeekInput"; import { DayOfWeekInput } from "@/components/form/DayOfWeekInput";
import SelectInput from "@/components/form/SelectInput"; import SelectInput from "@/components/form/SelectInput";
import { useCourseListInTermQuery } from "@/hooks/canvas/canvasCourseHooks";
import { useCanvasTermsQuery } from "@/hooks/canvas/canvasHooks"; import { useCanvasTermsQuery } from "@/hooks/canvas/canvasHooks";
import { useEmptyDirectoriesQuery } from "@/hooks/localCourse/storageDirectoryHooks";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel"; import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
import { DayOfWeek } from "@/models/local/localCourse"; import { DayOfWeek } from "@/models/local/localCourse";
import React, { useState } from "react"; import React, { useMemo, useState } from "react";
const sampleCompose = `
services:
canvas_manager:
image: alexmickelson/canvas_management:2
user: 1000:1000 # userid:groupid that matches file ownership on host system
ports:
- 8080:8080 # hostPort:containerPort - you can change the first one if you like
env_file:
- .env # needs to have your CANVAS_TOKEN set
environment:
- storageDirectory=/app/storage
- TZ=America/Denver
volumes:
- ~/projects/faculty/1430/2024-fall-alex/modules:/app/storage/UX
- ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend
- ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/intro_to_web
- ~/projects/faculty/1420/2024-fall/Modules:/app/storage/1420
- ~/projects/faculty/1425/2024-fall/Modules:/app/storage/1425
`
export default function NewCourseForm() { export default function NewCourseForm() {
const { data: canvasTerms } = useCanvasTermsQuery(new Date()); const today = useMemo(() => new Date(), []);
const { data: canvasTerms } = useCanvasTermsQuery(today);
const { data: emptyDirectories } = useEmptyDirectoriesQuery();
const [selectedTerm, setSelectedTerm] = useState< const [selectedTerm, setSelectedTerm] = useState<
CanvasEnrollmentTermModel | undefined CanvasEnrollmentTermModel | undefined
>(); >();
const { data: canvasCourses } = useCourseListInTermQuery(selectedTerm?.id);
const [selectedDaysOfWeek, setSelectedDaysOfWeek] = useState<DayOfWeek[]>([]); const [selectedDaysOfWeek, setSelectedDaysOfWeek] = useState<DayOfWeek[]>([]);
const [selectedCanvasCourse, setSelectedCanvasCourse] = useState<
CanvasCourseModel | undefined
>();
const [selectedDirectory, setSelectedDirectory] = useState<
string | undefined
>();
return ( return (
<div> <div>
@@ -23,7 +54,22 @@ export default function NewCourseForm() {
getOptionName={(t) => t.name} getOptionName={(t) => t.name}
/> />
{selectedTerm && ( {selectedTerm && (
<div> <>
<SelectInput
value={selectedCanvasCourse}
setValue={setSelectedCanvasCourse}
label={"Course"}
options={canvasCourses}
getOptionName={(c) => c.name}
/>
<SelectInput
value={selectedDirectory}
setValue={setSelectedDirectory}
label={"Storage Folder"}
options={emptyDirectories}
getOptionName={(d) => d}
/>
<br />
<DayOfWeekInput <DayOfWeekInput
selectedDays={selectedDaysOfWeek} selectedDays={selectedDaysOfWeek}
updateSettings={(day) => { updateSettings={(day) => {
@@ -36,8 +82,9 @@ export default function NewCourseForm() {
}); });
}} }}
/> />
</div> </>
)} )}
</div> </div>
); );
} }

View File

@@ -50,12 +50,6 @@ export async function GET(
return withErrorHandling(async () => { return withErrorHandling(async () => {
try { try {
const url = getUrl(params); const url = getUrl(params);
// const response = await axiosClient.get(url, {
// headers: {
// // Include other headers from the incoming request if needed:
// "Content-Type": "application/json",
// },
// });
var requestCount = 1; var requestCount = 1;
url.searchParams.set("per_page", "100"); url.searchParams.set("per_page", "100");
@@ -100,7 +94,7 @@ export async function POST(
try { try {
const url = getUrl(params); const url = getUrl(params);
const body = await req.json(); const body = await req.json();
const response = await axiosClient.post(url, body); const response = await axiosClient.post(url.toString(), body);
const headers = proxyResponseHeaders(response); const headers = proxyResponseHeaders(response);
return new NextResponse(JSON.stringify(response.data), { headers }); return new NextResponse(JSON.stringify(response.data), { headers });
@@ -123,7 +117,7 @@ export async function PUT(
try { try {
const url = getUrl(params); const url = getUrl(params);
const body = await req.json(); const body = await req.json();
const response = await axiosClient.put(url, body); const response = await axiosClient.put(url.toString(), body);
const headers = proxyResponseHeaders(response); const headers = proxyResponseHeaders(response);
return new NextResponse(JSON.stringify(response.data), { headers }); return new NextResponse(JSON.stringify(response.data), { headers });
@@ -143,7 +137,7 @@ export async function DELETE(
return withErrorHandling(async () => { return withErrorHandling(async () => {
try { try {
const url = getUrl(params); const url = getUrl(params);
const response = await axiosClient.delete(url); const response = await axiosClient.delete(url.toString());
const headers = proxyResponseHeaders(response); const headers = proxyResponseHeaders(response);
return new NextResponse(JSON.stringify(response.data), { headers }); return new NextResponse(JSON.stringify(response.data), { headers });

View File

@@ -0,0 +1,9 @@
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { withErrorHandling } from "@/services/withErrorHandling";
export const GET = async () =>
await withErrorHandling(async () => {
const directories = await fileStorageService.getEmptyDirectories();
return Response.json(directories);
});

View File

@@ -8,8 +8,17 @@ export const canvasCourseKeys = {
["canvas", canavasId, "course details"] as const, ["canvas", canavasId, "course details"] as const,
assignmentGroups: (canavasId: number) => assignmentGroups: (canavasId: number) =>
["canvas", canavasId, "assignment groups"] as const, ["canvas", canavasId, "assignment groups"] as const,
courseListInTerm: (canvasTermId: number | undefined) =>
["canvas courses in term", canvasTermId] as const,
}; };
export const useCourseListInTermQuery = (canvasTermId: number | undefined) =>
useSuspenseQuery({
queryKey: canvasCourseKeys.courseListInTerm(canvasTermId),
queryFn: async () =>
canvasTermId ? await canvasService.getCourses(canvasTermId) : [],
});
export const useCanvasCourseQuery = (canvasId: number) => export const useCanvasCourseQuery = (canvasId: number) =>
useSuspenseQuery({ useSuspenseQuery({
queryKey: canvasCourseKeys.courseDetails(canvasId), queryKey: canvasCourseKeys.courseDetails(canvasId),

View File

@@ -0,0 +1,16 @@
import { axiosClient } from "@/services/axiosUtils";
import { useSuspenseQuery } from "@tanstack/react-query";
export const directoryKeys = {
emptyFolders: ["empty folders"] as const,
};
export const useEmptyDirectoriesQuery = () =>
useSuspenseQuery({
queryKey: directoryKeys.emptyFolders,
queryFn: async () => {
const url = "/api/directories/empty";
const { data } = await axiosClient.get<string[]>(url);
return data;
},
});

View File

@@ -10,9 +10,11 @@ const baseCanvasUrl = "https://snow.instructure.com/api/v1";
const getAllTerms = async () => { const getAllTerms = async () => {
const url = `${baseCanvasUrl}/accounts/10/terms`; const url = `${baseCanvasUrl}/accounts/10/terms`;
const {data} = await axiosClient.get<{ const { data } = await axiosClient.get<
enrollment_terms: CanvasEnrollmentTermModel[]; {
}[]>(url); enrollment_terms: CanvasEnrollmentTermModel[];
}[]
>(url);
const terms = data.flatMap((r) => r.enrollment_terms); const terms = data.flatMap((r) => r.enrollment_terms);
return terms; return terms;
}; };
@@ -21,11 +23,12 @@ export const canvasService = {
getAllTerms, getAllTerms,
async getCourses(termId: number) { async getCourses(termId: number) {
const url = `${baseCanvasUrl}/courses`; const url = `${baseCanvasUrl}/courses`;
const coursesResponse = const response = await axiosClient.get<CanvasCourseModel[][]>(url);
await canvasServiceUtils.paginatedRequest<CanvasCourseModel>({ url }); const allCourses = response.data;
return coursesResponse const coursesInTerm = allCourses
.flat() .flatMap((l) => l)
.filter((c) => c.enrollment_term_id === termId); .filter((c) => c.enrollment_term_id === termId);
return coursesInTerm;
}, },
async getCourse(courseId: number): Promise<CanvasCourseModel> { async getCourse(courseId: number): Promise<CanvasCourseModel> {

View File

@@ -32,17 +32,24 @@ export const fileStorageService = {
const courseDirectories = await fs.readdir(basePath, { const courseDirectories = await fs.readdir(basePath, {
withFileTypes: true, withFileTypes: true,
}); });
const coursePromises = courseDirectories const coursePromises = await Promise.all(
.filter((dirent) => dirent.isDirectory()) courseDirectories
.filter(async (dirent) => { .filter((dirent) => dirent.isDirectory())
const coursePath = path.join(basePath, dirent.name); .map(async (dirent) => {
const settingsPath = path.join(coursePath, "settings.yml"); const coursePath = path.join(basePath, dirent.name);
return await directoryOrFileExists(settingsPath); const settingsPath = path.join(coursePath, "settings.yml");
}); const hasSettings = await directoryOrFileExists(settingsPath);
const courseNamesFromDirectories = (await Promise.all(coursePromises)).map( return {
(c) => c.name dirent,
hasSettings,
};
})
); );
const courseNamesFromDirectories = coursePromises
.filter(({ hasSettings }) => hasSettings)
.map(({ dirent }) => dirent.name);
return courseNamesFromDirectories; return courseNamesFromDirectories;
}, },
@@ -256,10 +263,22 @@ export const fileStorageService = {
} }
const directories = await fs.readdir(basePath, { withFileTypes: true }); const directories = await fs.readdir(basePath, { withFileTypes: true });
const emptyDirectories = directories console.log(directories);
.filter((dirent) => dirent.isDirectory()) const emptyDirectories = (
.map((dirent) => path.join(basePath, dirent.name)) await Promise.all(
.filter(async (dir) => !(await hasFileSystemEntries(dir))); directories
.filter((dirent) => dirent.isDirectory())
.map((dirent) => path.join(dirent.name))
.map(async (directory) => {
return {
directory,
files: await fs.readdir(path.join(basePath, directory)),
};
})
)
)
.filter(({ files }) => files.length === 0)
.map(({ directory }) => directory);
return emptyDirectories; return emptyDirectories;
}, },