feat: add gradebook frontend API types
This commit is contained in:
46
src/api.ts
46
src/api.ts
@@ -14,6 +14,8 @@ import type {
|
||||
AwardItemIn,
|
||||
AwardItemUpdateIn,
|
||||
AwardItemManageOut,
|
||||
GradebookOut,
|
||||
GradebookQuery,
|
||||
ShowcaseSubmissionLookupOut,
|
||||
ShowcaseDetail,
|
||||
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 = {
|
||||
async listConversations(taskId?: number, userId?: number) {
|
||||
const params: Record<string, number> = {}
|
||||
|
||||
@@ -161,6 +161,58 @@ export interface TaskStatsOut {
|
||||
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 {
|
||||
submission_id: string
|
||||
username: string
|
||||
|
||||
Reference in New Issue
Block a user