Cancel Training
linter / quality (push) Failing after 1m11s
tests / ci (8.3) (push) Successful in 3m55s

This commit is contained in:
2026-09-18 23:08:19 +02:00
parent d80bfe3cdd
commit 25b03fc39a
11 changed files with 168 additions and 33 deletions
+96 -22
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { router, useForm } from '@inertiajs/vue3';
import { ref, watch } from 'vue';
import {
Form,
@@ -12,6 +12,7 @@ import {
NativeSelect,
NativeSelectOption,
} from '@/components/ui/native-select';
import { cancel } from '@/routes/perceptron';
import type {
Dataset,
InitializationMethod,
@@ -23,8 +24,9 @@ import Card from './ui/card/Card.vue';
import CardContent from './ui/card/CardContent.vue';
import CardHeader from './ui/card/CardHeader.vue';
import CardTitle from './ui/card/CardTitle.vue';
import Input from './ui/input/Input.vue';
import FormError from './ui/form/FormError.vue';
import Input from './ui/input/Input.vue';
import Spinner from './ui/spinner/Spinner.vue';
const props = defineProps<{
type: PerceptronType;
@@ -98,43 +100,58 @@ watch(maxIterations, (value) => {
watch(selectedDatasetCopy, (newvalue) => {
form.clearErrors('dataset');
const selectedDatasetCopy = props.datasets.find(
(dataset) => dataset.label === newvalue
) || null;
const selectedDatasetCopy =
props.datasets.find((dataset) => dataset.label === newvalue) || null;
// LearningRate
learningRate.value = props.defaultLearningRate;
if (selectedDatasetCopy && selectedDatasetCopy.defaultLearningRate !== undefined) {
if (
selectedDatasetCopy &&
selectedDatasetCopy.defaultLearningRate !== undefined
) {
learningRate.value = selectedDatasetCopy.defaultLearningRate;
}
// MinError
minError.value = props.minError;
if (selectedDatasetCopy && selectedDatasetCopy.defaultMinError !== undefined) {
if (
selectedDatasetCopy &&
selectedDatasetCopy.defaultMinError !== undefined
) {
minError.value = selectedDatasetCopy.defaultMinError;
}
// MaxIterations
maxIterations.value = props.defaultMaxIterations;
if (selectedDatasetCopy && selectedDatasetCopy.defaultMaxIterations !== undefined) {
if (
selectedDatasetCopy &&
selectedDatasetCopy.defaultMaxIterations !== undefined
) {
maxIterations.value = selectedDatasetCopy.defaultMaxIterations;
}
// HiddenLayers
hiddenLayers.value = props.hiddenLayers;
if (selectedDatasetCopy && selectedDatasetCopy.defaultHiddenLayers !== undefined) {
if (
selectedDatasetCopy &&
selectedDatasetCopy.defaultHiddenLayers !== undefined
) {
hiddenLayers.value = selectedDatasetCopy.defaultHiddenLayers;
}
hiddenLayersNeurons.value = props.hiddenLayersNeurons;
if (selectedDatasetCopy && selectedDatasetCopy.defaultHiddenLayersNeurons !== undefined) {
hiddenLayersNeurons.value = selectedDatasetCopy.defaultHiddenLayersNeurons;
if (
selectedDatasetCopy &&
selectedDatasetCopy.defaultHiddenLayersNeurons !== undefined
) {
hiddenLayersNeurons.value =
selectedDatasetCopy.defaultHiddenLayersNeurons;
}
})
});
const trainingId = ref<string>('');
const trainingId = ref<string>('');
function startTraining() {
if (!selectedDatasetCopy.value) {
form.setError(
'dataset',
'Un dataset est nécessaire avant de lancer l\'entraînement.',
"Un dataset est nécessaire avant de lancer l'entraînement.",
);
console.log(form.errors);
return;
@@ -169,6 +186,21 @@ function startTraining() {
}
const emit = defineEmits(['update:selectedDataset', 'update:trainingId']);
async function cancelTraining() {
form.cancel();
router.post(
cancel(),
{
training_id: trainingId.value,
},
{
preserveScroll: true,
},
);
}
watch(selectedDatasetCopy, (newValue) => {
emit('update:selectedDataset', newValue);
});
@@ -182,6 +214,7 @@ watch(selectedDatasetCopy, (newValue) => {
<CardContent>
<Form
class="grid auto-cols-max grid-flow-row grid-cols-1 gap-4 space-y-6 md:grid-cols-2"
cancel-on-unmount
>
<!-- DATASET -->
<FormField name="dataset">
@@ -206,7 +239,12 @@ watch(selectedDatasetCopy, (newValue) => {
</NativeSelectOption>
</NativeSelect>
</FormControl>
<FormError :error="form.errors.dataset || props.errors?.selectedDatasetCopy" />
<FormError
:error="
form.errors.dataset ||
props.errors?.selectedDatasetCopy
"
/>
</FormItem>
</FormField>
@@ -224,7 +262,9 @@ watch(selectedDatasetCopy, (newValue) => {
class="cursor-pointer"
>
<NativeSelectOption
v-for="method in (props.type == 'multilayer' ? ['random'] : ['zeros', 'random'])"
v-for="method in props.type == 'multilayer'
? ['random']
: ['zeros', 'random']"
v-bind:key="method"
:value="method"
>
@@ -236,7 +276,10 @@ watch(selectedDatasetCopy, (newValue) => {
</FormField>
<!-- HIDDEN LAYERS -->
<FormField name="hidden_layers" v-if="props.type === 'multilayer'">
<FormField
name="hidden_layers"
v-if="props.type === 'multilayer'"
>
<FormItem>
<FormLabel>Nombre de couches cachées</FormLabel>
<FormControl>
@@ -255,9 +298,14 @@ watch(selectedDatasetCopy, (newValue) => {
</FormField>
<!-- HIDDEN LAYERS NEURONS -->
<FormField name="hidden_layers_neurons" v-if="props.type === 'multilayer'">
<FormField
name="hidden_layers_neurons"
v-if="props.type === 'multilayer'"
>
<FormItem>
<FormLabel>Nombre de neurones par couche cachée</FormLabel>
<FormLabel
>Nombre de neurones par couche cachée</FormLabel
>
<FormControl>
<!-- TODO : MAX input -->
<Input
@@ -319,13 +367,39 @@ watch(selectedDatasetCopy, (newValue) => {
@input="handleMaxIterationsInput"
/>
</FormControl>
<div v-if="form.errors.max_iterations || props.errors.max_iterations">
{{ form.errors.max_iterations || props.errors.max_iterations }}
<div
v-if="
form.errors.max_iterations ||
props.errors.max_iterations
"
>
{{
form.errors.max_iterations ||
props.errors.max_iterations
}}
</div>
</FormItem>
</FormField>
</Form>
<Button variant="outline" class="cursor-pointer mt-6" @click="startTraining">Lancer</Button>
<Transition name="fade">
<Button
variant="outline"
class="mt-6 cursor-pointer"
:disabled="form.processing"
@click="startTraining"
>Lancer<Spinner v-if="form.processing" class="ml-1"
/></Button>
</Transition>
<Transition name="fade">
<Button
variant="outline"
class="mt-6 ml-4 cursor-pointer"
@click="cancelTraining"
v-if="form.processing"
>Annuler</Button
>
</Transition>
</CardContent>
</Card>
</template>