Files
Inventory/app/pages/component-category/[id]/edit.vue
Matthieu 480aaa24b2 feat(navigation) : preserve list state in URL and use browser history for back buttons
Add useUrlState composable to sync page, search, sort and filter state
with URL query params. Back/forward navigation now restores the exact
list position. Replace hardcoded NuxtLink back buttons with
router.back() across all create/edit pages. Fix documents attachment
filter that checked non-existent ID fields instead of relation objects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 16:48:40 +01:00

156 lines
4.6 KiB
Vue

<template>
<main class="mx-auto flex w-full max-w-4xl flex-col gap-8 px-4 py-8 sm:px-6 lg:px-8">
<header class="space-y-2">
<div class="flex items-center justify-between gap-4">
<div>
<h1 class="text-3xl font-bold text-base-content">{{ title }}</h1>
<p class="text-base text-base-content/70">
Ajustez le squelette et les métadonnées de cette catégorie de composant. Les modifications seront appliquées lors des prochaines créations de composants.
</p>
</div>
<button type="button" class="btn btn-ghost" @click="$router.back()">
Retour au catalogue
</button>
</div>
</header>
<section class="rounded-xl border border-base-300 bg-base-100 p-6 shadow-sm">
<div v-if="loading" class="flex items-center justify-center py-16">
<span class="loading loading-spinner loading-lg" aria-hidden="true"></span>
<span class="ml-3 text-sm text-base-content/70">Chargement de la catégorie</span>
</div>
<ModelTypeForm
v-else
mode="edit"
initial-category="COMPONENT"
:initial-data="initialData"
:lock-category="true"
:saving="saving"
:disable-submit="isSubmitBlocked"
:disable-submit-message="submitBlockMessage"
:restricted-mode="isRestrictedMode"
:restricted-mode-message="restrictedModeMessage"
@submit="handleSubmit"
@cancel="handleCancel"
/>
</section>
</main>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useHead, useRoute, useRouter } from '#imports'
import ModelTypeForm from '~/components/model-types/ModelTypeForm.vue'
import { getModelType, updateModelType, type ModelTypePayload } from '~/services/modelTypes'
import type { ComponentModelStructure } from '~/shared/types/inventory'
import { useCategoryEditGuard } from '~/composables/useCategoryEditGuard'
import { useComponentTypes } from '~/composables/useComponentTypes'
import { useToast } from '~/composables/useToast'
const route = useRoute()
const router = useRouter()
const { showError, showSuccess } = useToast()
const { loadComponentTypes } = useComponentTypes()
const loading = ref(true)
const saving = ref(false)
const initialData = ref<Partial<ModelTypePayload> | null>(null)
const {
isRestrictedMode,
isSubmitBlocked,
restrictedModeMessage,
submitBlockMessage,
loadLinkedCount,
guardSubmitOrNotify,
} = useCategoryEditGuard({
endpoint: '/composants',
filterKey: 'typeComposant',
labels: {
singular: 'composant',
plural: 'composants',
verifying: 'Vérification des composants liés en cours…',
},
})
const title = computed(() =>
initialData.value?.name
? `Modifier « ${initialData.value.name} »`
: 'Modifier une catégorie de composant',
)
useHead(() => ({
title: title.value,
}))
const navigateBackToList = async () => {
await router.push('/component-category').catch(() => {
showError("Navigation impossible vers la liste des catégories.")
})
}
const normalizeError = (error: any) => {
const message = error?.data?.message || error?.message || 'Une erreur est survenue.'
return Array.isArray(message) ? message[0] : message
}
const loadCategory = async () => {
loading.value = true
try {
const id = String(route.params.id)
const response = await getModelType(id)
if (response.category !== 'COMPONENT') {
showError("Cette catégorie n'est pas un composant." )
await navigateBackToList()
return
}
initialData.value = {
name: response.name,
code: response.code,
category: response.category,
notes: response.notes ?? response.description ?? '',
structure: (response.structure as ComponentModelStructure | null) ?? undefined,
}
await loadLinkedCount(id)
} catch (error) {
showError(normalizeError(error))
await navigateBackToList()
} finally {
loading.value = false
}
}
const handleCancel = () => {
navigateBackToList()
}
const handleSubmit = async (payload: Parameters<typeof updateModelType>[1]) => {
if (guardSubmitOrNotify()) {
return
}
const id = String(route.params.id)
saving.value = true
try {
const enrichedPayload = {
...payload,
description: payload?.notes ?? null,
}
await updateModelType(id, enrichedPayload)
await loadComponentTypes({ force: true })
showSuccess('Catégorie de composant mise à jour avec succès.')
await navigateBackToList()
} catch (error) {
showError(normalizeError(error))
} finally {
saving.value = false
}
}
onMounted(() => {
loadCategory()
})
</script>