119 lines
3.2 KiB
Svelte
119 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import { form, field } from 'svelte-forms';
|
|
import { required, max, min } from 'svelte-forms/validators';
|
|
import FileInput from '../forms/FileInput.svelte';
|
|
import InputWithLabel from '../forms/InputWithLabel.svelte';
|
|
import { getContext } from 'svelte';
|
|
import { createExo, editExo } from '../../requests/exo.request';
|
|
import type { Exercice } from '../../types/exo.type';
|
|
import { checkFile, errorMsg } from '../../utils/forms';
|
|
import { compareObject } from '../../utils/utils';
|
|
import { goto } from '$app/navigation';
|
|
export let editing = true;
|
|
export let updateExo: Function = (e: Exercice) => {};
|
|
|
|
export let exo: Exercice | null = null;
|
|
export let cancel: Function;
|
|
|
|
const { alert } = getContext<{ alert: Function }>('alert');
|
|
|
|
// "Legally" initiate empty FileList for model field (simple list raises warning)
|
|
let list = new DataTransfer();
|
|
let file = new File(['content'], !editing || exo == null ? 'filename.py' : exo.exo_source);
|
|
list.items.add(file);
|
|
!editing && list.items.remove(0);
|
|
|
|
// Initiate fields and form
|
|
const name = field('name', !!exo ? exo.name : '', [required(), max(50), min(5)], {
|
|
checkOnInit: true
|
|
});
|
|
const consigne = field('consigne', !!exo && exo.consigne != null ? exo.consigne : '', [max(200)], { checkOnInit: true });
|
|
const prv = field('private', !!exo ? exo.private : false);
|
|
const model = field('model', list.files, [checkFile(), required()], {
|
|
checkOnInit: !editing
|
|
});
|
|
const myForm = form(name, consigne, prv, model);
|
|
</script>
|
|
|
|
<form
|
|
action=""
|
|
on:submit|preventDefault={() => {
|
|
if (editing && exo != null) {
|
|
editExo(exo.id_code, {
|
|
name: $name.value,
|
|
consigne: $consigne.value,
|
|
private: $prv.value,
|
|
...($model.dirty == true && { file: $model.value[0] })
|
|
}).then((r) => {
|
|
exo=r.data
|
|
updateExo(r.data);
|
|
cancel()
|
|
});
|
|
} else {
|
|
createExo({
|
|
name: $name.value,
|
|
consigne: $consigne.value,
|
|
private: $prv.value,
|
|
file: $model.value[0]
|
|
}).then((r) => {
|
|
updateExo(r.data);
|
|
cancel()
|
|
});
|
|
}
|
|
}}
|
|
>
|
|
<InputWithLabel
|
|
type="text"
|
|
bind:value={$name.value}
|
|
maxlength="50"
|
|
minlength="5"
|
|
required
|
|
label="Nom"
|
|
errors={errorMsg($myForm, 'name')}
|
|
/>
|
|
|
|
<InputWithLabel
|
|
type="text"
|
|
bind:value={$consigne.value}
|
|
maxlength="200"
|
|
label="Consigne"
|
|
errors={errorMsg($myForm, 'consigne')}
|
|
/>
|
|
|
|
<div>
|
|
<input type="checkbox" bind:checked={$prv.value} name="private" id="private" />
|
|
<label for="private">Privé</label>
|
|
</div>
|
|
<FileInput bind:value={$model.value} accept=".py" id_code={exo?.id_code} />
|
|
|
|
<div class="wp-100">
|
|
<button class="primary-btn" disabled={!$myForm.valid}>Valider</button>
|
|
<button
|
|
class="danger-btn"
|
|
on:click|preventDefault={() => {
|
|
|
|
if (exo != null && ($model.dirty || !compareObject({...exo, consigne: exo.consigne == null ? "": exo.consigne}, myForm.summary()))) {
|
|
alert({
|
|
title: 'test',
|
|
description:
|
|
'Aliquip in cupidatat anim tempor quis est sint qui sunt. Magna consequat excepteur deserunt ullamco quis.',
|
|
validate: cancel
|
|
});
|
|
} else {
|
|
cancel();
|
|
}
|
|
}}>Annuler</button
|
|
>
|
|
</div>
|
|
</form>
|
|
|
|
<style>
|
|
form {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
align-items: flex-start;
|
|
}
|
|
</style>
|