Skip to content
Extraits de code Groupes Projets
Valider f5677b8d rédigé par Brieuc Dubois's avatar Brieuc Dubois
Parcourir les fichiers

Create and edit test groups

parent 8bdf47e1
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -90,13 +90,44 @@ def remove_group_from_test_task( ...@@ -90,13 +90,44 @@ def remove_group_from_test_task(
def create_group( def create_group(
db: Session, group: schemas.TestTaskGroupCreate db: Session, group: schemas.TestTaskGroupCreate
) -> models.TestTaskGroup: ) -> models.TestTaskGroup:
db_group = models.TestTaskGroup(**group.model_dump()) db_group = models.TestTaskGroup(
**group.model_dump(exclude_unset=True, exclude={"questions"})
)
if group.questions:
db_group.questions = (
db.query(models.TestTaskQuestion)
.filter(models.TestTaskQuestion.id.in_(group.questions))
.all()
)
db.add(db_group) db.add(db_group)
db.commit() db.commit()
db.refresh(db_group) db.refresh(db_group)
return db_group return db_group
def update_group(
db: Session, group: schemas.TestTaskGroupCreate, group_id: int
) -> None:
current = db.query(models.TestTaskGroup).filter(models.TestTaskGroup.id == group_id)
current.update(
{
**group.model_dump(exclude_unset=True, exclude={"questions"}),
}
)
first = current.first()
if first:
first.questions = (
db.query(models.TestTaskQuestion)
.filter(models.TestTaskQuestion.id.in_(group.questions))
.all()
)
db.commit()
def get_group(db: Session, group_id: int) -> models.TestTaskGroup | None: def get_group(db: Session, group_id: int) -> models.TestTaskGroup | None:
return ( return (
db.query(models.TestTaskGroup) db.query(models.TestTaskGroup)
......
...@@ -49,6 +49,35 @@ def get_groups( ...@@ -49,6 +49,35 @@ def get_groups(
return crud.get_groups(db) return crud.get_groups(db)
@require_admin("You do not have permission to get a group.")
@testRouter.get("/groups/{group_id}", response_model=schemas.TestTaskGroup)
def get_group(
group_id: int,
db: Session = Depends(get_db),
):
group = crud.get_group(db, group_id)
if group is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Group not found"
)
return group
@require_admin("You do not have permission to edit a group.")
@testRouter.put("/groups/{group_id}", status_code=status.HTTP_204_NO_CONTENT)
def update_group(
group_id: int,
group: schemas.TestTaskGroupCreate,
db: Session = Depends(get_db),
):
db_group = crud.get_group(db, group_id)
if db_group is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Group not found"
)
crud.update_group(db, group, group_id)
@require_admin("You do not have permission to get all the questions.") @require_admin("You do not have permission to get all the questions.")
@testRouter.get("/questions", response_model=list[schemas.TestTaskQuestion]) @testRouter.get("/questions", response_model=list[schemas.TestTaskQuestion])
def get_questions( def get_questions(
......
...@@ -65,6 +65,7 @@ class TestTaskGroupCreate(BaseModel): ...@@ -65,6 +65,7 @@ class TestTaskGroupCreate(BaseModel):
title: str title: str
demo: bool = False demo: bool = False
randomize: bool = True randomize: bool = True
questions: list[int] = []
class TestTypingCreate(BaseModel): class TestTypingCreate(BaseModel):
...@@ -74,8 +75,11 @@ class TestTypingCreate(BaseModel): ...@@ -74,8 +75,11 @@ class TestTypingCreate(BaseModel):
duration: int | None = None duration: int | None = None
class TestTaskGroup(TestTaskGroupCreate): class TestTaskGroup(BaseModel):
# id: int id: int | None = None
title: str
demo: bool = False
randomize: bool = True
questions: list[TestTaskQuestion] = [] questions: list[TestTaskQuestion] = []
......
...@@ -195,6 +195,13 @@ export async function getTestGroupsAPI(fetch: fetchType): Promise<any> { ...@@ -195,6 +195,13 @@ export async function getTestGroupsAPI(fetch: fetchType): Promise<any> {
return groups; return groups;
} }
export async function getTestTaskGroupAPI(fetch: fetchType, id: number): Promise<any> {
const response = await fetch(`/api/tests/groups/${id}`);
if (!response.ok) return null;
const group = await response.json();
return group;
}
export async function getTestQuestionsAPI(fetch: fetchType): Promise<any> { export async function getTestQuestionsAPI(fetch: fetchType): Promise<any> {
const response = await fetch(`/api/tests/questions`); const response = await fetch(`/api/tests/questions`);
if (!response.ok) return null; if (!response.ok) return null;
...@@ -240,3 +247,46 @@ export async function updateTestTaskAPI( ...@@ -240,3 +247,46 @@ export async function updateTestTaskAPI(
}); });
return response.ok; return response.ok;
} }
export async function createTestTaskGroupAPI(
fetch: fetchType,
title: string,
demo: boolean,
randomize: boolean,
questions: number[]
): Promise<number | null> {
const response = await fetch(`/api/tests/groups`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title,
demo,
randomize,
questions
})
});
if (!response.ok) return null;
const group = await response.json();
return group.id;
}
export async function updateTestTaskGroupAPI(
fetch: fetchType,
id: number,
title: string,
demo: boolean,
randomize: boolean,
questions: number[]
): Promise<boolean> {
const response = await fetch(`/api/tests/groups/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title,
demo,
randomize,
questions
})
});
return response.ok;
}
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
{/each} {/each}
</tbody> </tbody>
</table> </table>
<div class="mt-8 mx-auto w-[64rem] flex justify-between"> <div class="mt-8 mx-auto w-[64rem] flex justify-between pb-8">
<a class="button" href="/admin/tests/new">{$t('tests.create')}</a> <a class="button" href="/admin/tests/new">{$t('tests.create')}</a>
<span> <span>
<a class="btn" href="/admin/studies">{$t('tests.backtostudies')}</a> <a class="btn" href="/admin/studies">{$t('tests.backtostudies')}</a>
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
{/each} {/each}
</tbody> </tbody>
</table> </table>
<div class="mt-8 mx-auto w-[64rem] flex justify-between"> <div class="mt-8 mx-auto w-[64rem] flex justify-between pb-8">
<a class="button" href="/admin/tests/groups/new">{$t('tests.groups.create')}</a> <a class="button" href="/admin/tests/groups/new">{$t('tests.groups.create')}</a>
<span> <span>
<a class="btn" href="/admin/tests">{$t('tests.groups.backtotests')}</a> <a class="btn" href="/admin/tests">{$t('tests.groups.backtotests')}</a>
......
import { redirect, type Actions } from '@sveltejs/kit'; import { redirect, type Actions } from '@sveltejs/kit';
import { updateTestTypingAPI } from '$lib/api/tests'; import { updateTestTaskGroupAPI } from '$lib/api/tests';
export const actions: Actions = { export const actions: Actions = {
default: async ({ request, fetch }) => { default: async ({ request, fetch }) => {
...@@ -7,9 +7,10 @@ export const actions: Actions = { ...@@ -7,9 +7,10 @@ export const actions: Actions = {
const idStr = formData.get('id')?.toString(); const idStr = formData.get('id')?.toString();
const title = formData.get('title')?.toString(); const title = formData.get('title')?.toString();
const type = formData.get('type')?.toString(); const demo = formData.get('demo')?.toString() == 'on';
const randomize = formData.get('randomize')?.toString() == 'on';
if (!title || !type || !idStr || (type !== 'typing' && type !== 'task')) { if (!idStr || !title) {
return { return {
message: 'Invalid request: Missing required fields' message: 'Invalid request: Missing required fields'
}; };
...@@ -23,36 +24,19 @@ export const actions: Actions = { ...@@ -23,36 +24,19 @@ export const actions: Actions = {
}; };
} }
if (type === 'typing') { const questions = formData
const explanation = formData.get('explanation')?.toString(); .getAll('questions[]')
const text = formData.get('text')?.toString(); .map((question) => parseInt(question.toString(), 10))
const repeatStr = formData.get('repeat')?.toString(); .filter((question) => !isNaN(question));
const durationStr = formData.get('duration')?.toString();
if (!explanation || !text || !repeatStr || !durationStr) { const ok = await updateTestTaskGroupAPI(fetch, id, title, demo, randomize, questions);
return {
message: 'Invalid request: Missing required fields'
};
}
const repeat = parseInt(repeatStr, 10); if (!ok) {
const duration = parseInt(durationStr, 10); return {
message: 'Error updating test task group'
if (isNaN(repeat) || isNaN(duration)) { };
return {
message: 'Invalid request: Invalid format for numbers'
};
}
const ok = await updateTestTypingAPI(fetch, id, title, explanation, text, repeat, duration);
if (!ok) {
return {
message: 'Invalid request: Failed to update test'
};
}
return redirect(303, `/admin/tests`);
} }
return redirect(303, `/admin/tests/groups`);
} }
}; };
<script lang="ts"> <script lang="ts">
import TestForm from '$lib/components/tests/TestForm.svelte'; import GroupForm from '$lib/components/tests/GroupForm.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
const { data }: { data: PageData } = $props(); const { data, form }: { data: PageData; form: FormData } = $props();
const { test, possibleGroups } = data; const { group, possibleQuestions } = data;
</script> </script>
<TestForm {test} {possibleGroups} /> <GroupForm {group} {possibleQuestions} message={form?.message} />
import { getTestAPI, getTestGroupsAPI } from '$lib/api/tests'; import { getTestQuestionsAPI, getTestTaskGroupAPI } from '$lib/api/tests';
import { Test } from '$lib/types/tests';
import TestTaskGroup from '$lib/types/testTaskGroups'; import TestTaskGroup from '$lib/types/testTaskGroups';
import { TestTaskQuestion } from '$lib/types/testTaskQuestions';
import { error, type Load } from '@sveltejs/kit'; import { error, type Load } from '@sveltejs/kit';
export const load: Load = async ({ fetch, params }) => { export const load: Load = async ({ fetch, params }) => {
const id = Number(params.id); const idStr = params?.id;
if (!idStr) {
return error(400, 'Invalid ID');
}
const id = parseInt(idStr, 10);
if (isNaN(id)) { if (isNaN(id)) {
return error(400, 'Invalid ID'); return error(400, 'Invalid ID');
} }
const testRaw = await getTestAPI(fetch, id); const groupRaw = await getTestTaskGroupAPI(fetch, id);
const test = Test.parse(testRaw);
if (!groupRaw) {
return error(404, 'Group not found');
}
const group = TestTaskGroup.parse(groupRaw);
const groupsRaw = await getTestGroupsAPI(fetch); const questionsRaw = await getTestQuestionsAPI(fetch);
const groups = TestTaskGroup.parseAll(groupsRaw); const questions = TestTaskQuestion.parseAll(questionsRaw);
return { test, possibleGroups: groups }; return { group, possibleQuestions: questions };
}; };
import { redirect, type Actions } from '@sveltejs/kit'; import { redirect, type Actions } from '@sveltejs/kit';
import { createTestTypingAPI } from '$lib/api/tests'; import { createTestTaskGroupAPI } from '$lib/api/tests';
export const actions: Actions = { export const actions: Actions = {
default: async ({ request, fetch }) => { default: async ({ request, fetch }) => {
...@@ -9,7 +9,7 @@ export const actions: Actions = { ...@@ -9,7 +9,7 @@ export const actions: Actions = {
const demo = formData.get('demo')?.toString() == 'on'; const demo = formData.get('demo')?.toString() == 'on';
const randomize = formData.get('randomize')?.toString() == 'on'; const randomize = formData.get('randomize')?.toString() == 'on';
if (!title || !demo || !randomize) { if (!title) {
return { return {
message: 'Invalid request: Missing required fields' message: 'Invalid request: Missing required fields'
}; };
...@@ -22,6 +22,12 @@ export const actions: Actions = { ...@@ -22,6 +22,12 @@ export const actions: Actions = {
const id = await createTestTaskGroupAPI(fetch, title, demo, randomize, questions); const id = await createTestTaskGroupAPI(fetch, title, demo, randomize, questions);
return redirect(303, `/admin/tests`); if (id === null) {
return {
message: 'Error creating test task group'
};
}
return redirect(303, `/admin/tests/groups`);
} }
}; };
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter