feat: add gradebook frontend API types

This commit is contained in:
2026-05-02 07:57:28 -06:00
parent 3136be2df7
commit eff635fb49
2 changed files with 98 additions and 0 deletions

View File

@@ -14,6 +14,8 @@ import type {
AwardItemIn, AwardItemIn,
AwardItemUpdateIn, AwardItemUpdateIn,
AwardItemManageOut, AwardItemManageOut,
GradebookOut,
GradebookQuery,
ShowcaseSubmissionLookupOut, ShowcaseSubmissionLookupOut,
ShowcaseDetail, ShowcaseDetail,
PromptRound, PromptRound,
@@ -252,6 +254,50 @@ export const Submission = {
}, },
} }
function gradebookParams(query: GradebookQuery) {
const params: Record<string, string | boolean> = {
classname: query.classname,
}
if (query.task_type) params.task_type = query.task_type
if (query.username) params.username = query.username
if (query.include_all_tasks) params.include_all_tasks = true
return params
}
function filenameFromDisposition(
disposition: string | undefined,
fallback: string,
) {
const match = disposition?.match(/filename\*=UTF-8''([^;]+)/)
return match ? decodeURIComponent(match[1]) : fallback
}
export const Gradebook = {
async get(query: GradebookQuery): Promise<GradebookOut> {
const res = await http.get("/submission/gradebook/", {
params: gradebookParams(query),
})
return res.data
},
async downloadCsv(query: GradebookQuery) {
const res = await http.get("/submission/gradebook/export/", {
params: gradebookParams(query),
responseType: "blob",
})
const blob = new Blob([res.data], { type: "text/csv;charset=utf-8" })
const url = URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = filenameFromDisposition(
res.headers["content-disposition"],
`gradebook-${query.classname}.csv`,
)
a.click()
URL.revokeObjectURL(url)
},
}
export const Prompt = { export const Prompt = {
async listConversations(taskId?: number, userId?: number) { async listConversations(taskId?: number, userId?: number) {
const params: Record<string, number> = {} const params: Record<string, number> = {}

View File

@@ -161,6 +161,58 @@ export interface TaskStatsOut {
top_viewed: TopViewedItem[] top_viewed: TopViewedItem[]
} }
export type GradebookTaskType = "tutorial" | "challenge"
export type GradebookGrade = "A" | "B" | "C" | "D" | "E"
export interface GradebookQuery {
classname: string
task_type?: GradebookTaskType | ""
username?: string
include_all_tasks?: boolean
}
export interface GradebookTask {
id: number
display: number
title: string
task_type: GradebookTaskType
submitted_count: number
coverage: number
included: boolean
}
export interface GradebookCell {
score: number
submitted: boolean
submission_id: string | null
}
export interface GradebookRow {
user_id: number
username: string
classname: string
rank: number
grade: GradebookGrade
scores: Record<number, GradebookCell>
tutorial_total: number
challenge_total: number
total_score: number
average_score: number | null
submitted_task_count: number
missing_task_count: number
}
export interface GradebookOut {
classname: string
classes: string[]
task_count: number
included_task_count: number
student_count: number
coverage_threshold_count: number
tasks: GradebookTask[]
rows: GradebookRow[]
}
export interface ShowcaseItem { export interface ShowcaseItem {
submission_id: string submission_id: string
username: string username: string