feat: suppression des commandes PENDING depuis /commands
Build & Deploy / build (push) Successful in 40s
Build & Deploy / docker (push) Successful in 1m4s
Build & Deploy / deploy (push) Successful in 26s

- Ajout de destroy() dans CommandsController (DELETE /commands/:id)
- Routes DELETE /commands/:id dans les groupes /api/v1 et /internal
- Bouton supprimer dans Commands.vue visible uniquement sur les commandes PENDING
- Utilise fetchWithCsrf pour la protection CSRF
This commit is contained in:
kevin.lhereec committed 2026-07-17 10:31:56 +02:00
1 parent b22d3e9b56
commit b00c0c94a8
3 files changed
+51 -1

No files matched your search

+8
View File
@@ -28,4 +28,12 @@ export default class CommandsController {
return response.status(201).json(command)
}
async destroy({ params, response }: HttpContext) {
const deleted = await this.commandService.deleteCommand(params.id)
if (!deleted) {
return response.status(404).json({ error: 'Command not found' })
}
return response.status(204).send('')
}
}
+41 -1
View File
@@ -3,6 +3,7 @@ import { ref, computed } from 'vue'
import { router, Link } from '@inertiajs/vue3'
import { useI18n } from 'vue-i18n'
import TitleBar from '../components/TitleBar.vue'
import { fetchWithCsrf } from '../helpers/fetch_with_csrf'
const { t } = useI18n()
@@ -50,6 +51,27 @@ function removeFilter(key: keyof typeof localFilters.value) {
localFilters.value[key] = ''
applyFilters()
}
const deletingId = ref<string | null>(null)
const deleteError = ref('')
async function deleteCommand(id: string) {
if (!confirm('Supprimer cette commande PENDING ?')) return
deletingId.value = id
deleteError.value = ''
try {
const response = await fetchWithCsrf(`/internal/commands/${id}`, { method: 'DELETE' })
if (!response.ok) {
const payload = await response.json().catch(() => ({}))
throw new Error(payload.error || 'Échec de la suppression')
}
router.reload({ preserveState: true })
} catch (e) {
deleteError.value = e instanceof Error ? e.message : 'Erreur inconnue'
} finally {
deletingId.value = null
}
}
</script>
<template>
@@ -119,6 +141,12 @@ function removeFilter(key: keyof typeof localFilters.value) {
</span>
</div>
<!-- Error banner -->
<div v-if="deleteError" class="alert alert-danger alert-dismissible mb-3" role="alert">
{{ deleteError }}
<button type="button" class="btn-close" @click="deleteError = ''"></button>
</div>
<!-- Results count -->
<p class="text-muted small mb-2">{{ commands.length }} résultat(s)</p>
@@ -133,6 +161,7 @@ function removeFilter(key: keyof typeof localFilters.value) {
<th>{{ t('labels.mode') }}</th>
<th>{{ t('labels.priority') }}</th>
<th>{{ t('labels.creationDate') }}</th>
<th></th>
</tr>
</thead>
<tbody>
@@ -151,9 +180,20 @@ function removeFilter(key: keyof typeof localFilters.value) {
<td class="small">{{ cmd.mode }}</td>
<td class="small">{{ cmd.priority }}</td>
<td class="small">{{ cmd.createdAt ? new Date(cmd.createdAt).toLocaleString() : '' }}</td>
<td class="text-end">
<button
v-if="cmd.status === 'PENDING'"
class="btn btn-outline-danger btn-sm py-0 px-2"
style="font-size: 0.75rem"
:disabled="deletingId === cmd._id"
@click="deleteCommand(cmd._id)"
>
{{ deletingId === cmd._id ? '…' : '✕' }}
</button>
</td>
</tr>
<tr v-if="commands.length === 0">
<td colspan="6" class="text-center text-muted py-3">Aucune commande trouvée.</td>
<td colspan="7" class="text-center text-muted py-3">Aucune commande trouvée.</td>
</tr>
</tbody>
</table>
+2
View File
@@ -43,6 +43,7 @@ router
router.get('/commands', [CommandsController, 'index'])
router.get('/commands/:id', [CommandsController, 'show'])
router.post('/commands', [CommandsController, 'store'])
router.delete('/commands/:id', [CommandsController, 'destroy'])
router.get('/tr069-trace', [Tr069TraceController, 'index'])
router.post('/tr069-trace', [Tr069TraceController, 'store'])
@@ -100,6 +101,7 @@ router
router.get('/commands', [CommandsController, 'index'])
router.get('/commands/:id', [CommandsController, 'show'])
router.post('/commands', [CommandsController, 'store'])
router.delete('/commands/:id', [CommandsController, 'destroy'])
// TR-069 Trace
router.get('/tr069-trace', [Tr069TraceController, 'index'])