Restructure submissions
This commit is contained in:
parent
bf830b0849
commit
9a9315c5aa
@ -11,7 +11,7 @@ model User {
|
|||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
username String @unique
|
username String @unique
|
||||||
password String
|
password String
|
||||||
sessions Session[]
|
Submission Session[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Session {
|
model Session {
|
||||||
@ -31,9 +31,12 @@ model Submission {
|
|||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
state SubmissionState
|
state SubmissionState
|
||||||
expectedOutput String
|
|
||||||
actualOutput String
|
actualOutput String
|
||||||
message String?
|
message String?
|
||||||
|
team Team @relation(fields: [teamId], references: [id])
|
||||||
|
teamId Int
|
||||||
|
problem Problem @relation(fields: [problemId], references: [id])
|
||||||
|
problemId Int
|
||||||
}
|
}
|
||||||
|
|
||||||
model Problem {
|
model Problem {
|
||||||
@ -43,9 +46,11 @@ model Problem {
|
|||||||
sampleOutput String
|
sampleOutput String
|
||||||
realInput String
|
realInput String
|
||||||
realOutput String
|
realOutput String
|
||||||
|
Submission Submission[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Team {
|
model Team {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
name String @unique
|
name String @unique
|
||||||
|
Submission Submission[]
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
onMount(async () => {
|
||||||
|
await import('bootstrap');
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body class="container">
|
<body class="container">
|
||||||
|
@ -12,10 +12,14 @@ export const load = (async ({ params }) => {
|
|||||||
if (!submission) {
|
if (!submission) {
|
||||||
throw redirect(302, '/admin/reviews');
|
throw redirect(302, '/admin/reviews');
|
||||||
}
|
}
|
||||||
|
const problem = await db.problem.findUnique({ where: { id: submission.problemId } });
|
||||||
|
if (!problem) {
|
||||||
|
throw error(500, 'Invalid problem');
|
||||||
|
}
|
||||||
let diff = Diff.createTwoFilesPatch(
|
let diff = Diff.createTwoFilesPatch(
|
||||||
'expected',
|
'expected',
|
||||||
'actual',
|
'actual',
|
||||||
submission.expectedOutput,
|
problem.realOutput,
|
||||||
submission.actualOutput
|
submission.actualOutput
|
||||||
);
|
);
|
||||||
return { diff: diff };
|
return { diff: diff };
|
||||||
|
@ -3,13 +3,18 @@ import { SubmissionState } from '@prisma/client';
|
|||||||
import type { Actions, PageServerLoad } from './$types';
|
import type { Actions, PageServerLoad } from './$types';
|
||||||
|
|
||||||
export const load = (async () => {
|
export const load = (async () => {
|
||||||
const query = await db.submission.findMany({ where: { state: SubmissionState.InReview } });
|
const submissions = await db.submission.findMany({ where: { state: SubmissionState.InReview } });
|
||||||
query.sort((a, b) => {
|
const teams = await db.team.findMany();
|
||||||
return a.createdAt.valueOf() - b.createdAt.valueOf();
|
const problems = await db.problem.findMany();
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
reviewList: query.map((row) => {
|
reviewList: submissions.map((row) => {
|
||||||
return { id: row.id, createdAt: row.createdAt };
|
return { id: row.id, createdAt: row.createdAt };
|
||||||
|
}),
|
||||||
|
teams: teams.map((row) => {
|
||||||
|
return { id: row.id, name: row.name };
|
||||||
|
}),
|
||||||
|
problems: problems.map((row) => {
|
||||||
|
return { id: row.id, name: row.friendlyName };
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}) satisfies PageServerLoad;
|
}) satisfies PageServerLoad;
|
||||||
@ -17,20 +22,32 @@ export const load = (async () => {
|
|||||||
export const actions = {
|
export const actions = {
|
||||||
submission: async ({ request }) => {
|
submission: async ({ request }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const expected = data.get('expected');
|
const teamId = data.get('teamId');
|
||||||
|
const problemId = data.get('problemId');
|
||||||
const actual = data.get('actual');
|
const actual = data.get('actual');
|
||||||
if (!expected || !actual) {
|
if (!teamId || !problemId || !actual) {
|
||||||
return { success: false };
|
return { success: false };
|
||||||
}
|
}
|
||||||
if (expected.toString() === actual.toString()) {
|
const problemIdInt = parseInt(problemId.toString());
|
||||||
|
const teamIdInt = parseInt(teamId.toString());
|
||||||
|
if (isNaN(problemIdInt) || isNaN(teamIdInt)) {
|
||||||
|
return { success: false };
|
||||||
|
}
|
||||||
|
const problem = await db.problem.findUnique({ where: { id: problemIdInt } });
|
||||||
|
if (!problem) {
|
||||||
|
return { success: false };
|
||||||
|
}
|
||||||
|
if (problem.realOutput === actual.toString()) {
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
await db.submission.create({
|
await db.submission.create({
|
||||||
data: {
|
data: {
|
||||||
state: SubmissionState.InReview,
|
state: SubmissionState.InReview,
|
||||||
expectedOutput: expected.toString(),
|
actualOutput: actual.toString(),
|
||||||
actualOutput: actual.toString()
|
teamId: teamIdInt,
|
||||||
|
problemId: problemIdInt
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { success: true };
|
||||||
}
|
}
|
||||||
} satisfies Actions;
|
} satisfies Actions;
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
export let form: ActionData;
|
export let form: ActionData;
|
||||||
|
|
||||||
|
let selectedTeam: (typeof data.teams)[0] | null;
|
||||||
|
let selectedProblem: (typeof data.problems)[0] | null;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -30,15 +33,55 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<form method="POST" action="?/submission" use:enhance>
|
<form method="POST" action="?/submission" use:enhance>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-3">
|
||||||
<h5>Expected output (real data)</h5>
|
<h5>Team</h5>
|
||||||
<textarea name="expected" class="form-control" />
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||||
|
{selectedTeam ? selectedTeam.name : 'Select Team'}
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{#each data.teams as team}
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
selectedTeam = team;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
class="dropdown-item">{team.name}</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<h5>Problem</h5>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||||
|
{selectedProblem ? selectedProblem.name : 'Select Problem'}
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{#each data.problems as problem}
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
selectedProblem = problem;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
class="dropdown-item">{problem.name}</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<h5>Actual output (like from student output)</h5>
|
<h5>Actual output (like from student output)</h5>
|
||||||
<textarea name="actual" class="form-control" />
|
<textarea name="actual" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<input name="teamId" type="hidden" value={selectedTeam ? selectedTeam.id : ''} />
|
||||||
|
<input name="problemId" type="hidden" value={selectedProblem ? selectedProblem.id : ''} />
|
||||||
<div class="row justify-content-end">
|
<div class="row justify-content-end">
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<button type="submit" class="mt-3 btn btn-secondary">Submit</button>
|
<button type="submit" class="mt-3 btn btn-secondary">Submit</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user