Move category editor to full pages and simplify root skeleton
This commit is contained in:
124
app/pages/component-category/[id]/edit.vue
Normal file
124
app/pages/component-category/[id]/edit.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<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>
|
||||
<NuxtLink class="btn btn-ghost" to="/component-category">
|
||||
Retour au catalogue
|
||||
</NuxtLink>
|
||||
</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"
|
||||
@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 { useToast } from '~/composables/useToast'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { showError, showSuccess } = useToast()
|
||||
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
const initialData = ref<Partial<ModelTypePayload> | null>(null)
|
||||
|
||||
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 ?? undefined,
|
||||
}
|
||||
} catch (error) {
|
||||
showError(normalizeError(error))
|
||||
await navigateBackToList()
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
navigateBackToList()
|
||||
}
|
||||
|
||||
const handleSubmit = async (payload: Parameters<typeof updateModelType>[1]) => {
|
||||
const id = String(route.params.id)
|
||||
saving.value = true
|
||||
try {
|
||||
const enrichedPayload = {
|
||||
...payload,
|
||||
description: payload?.notes ?? null,
|
||||
}
|
||||
await updateModelType(id, enrichedPayload)
|
||||
showSuccess('Catégorie de composant mise à jour avec succès.')
|
||||
await navigateBackToList()
|
||||
} catch (error) {
|
||||
showError(normalizeError(error))
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadCategory()
|
||||
})
|
||||
</script>
|
||||
10
app/pages/component-category/index.vue
Normal file
10
app/pages/component-category/index.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<ManagementView
|
||||
category="COMPONENT"
|
||||
heading="Catégories de composant"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ManagementView from '~/components/model-types/ManagementView.vue'
|
||||
</script>
|
||||
68
app/pages/component-category/new.vue
Normal file
68
app/pages/component-category/new.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<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">Nouvelle catégorie de composant</h1>
|
||||
<p class="text-base text-base-content/70">
|
||||
Configurez le squelette canonique qui sera appliqué lors de la création des composants appartenant à cette catégorie.
|
||||
</p>
|
||||
</div>
|
||||
<NuxtLink class="btn btn-ghost" to="/component-category">
|
||||
Retour au catalogue
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="rounded-xl border border-base-300 bg-base-100 p-6 shadow-sm">
|
||||
<ModelTypeForm
|
||||
mode="create"
|
||||
initial-category="COMPONENT"
|
||||
:lock-category="true"
|
||||
:saving="saving"
|
||||
@submit="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
/>
|
||||
</section>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useHead, useRouter } from '#imports'
|
||||
import ModelTypeForm from '~/components/model-types/ModelTypeForm.vue'
|
||||
import { createModelType } from '~/services/modelTypes'
|
||||
import { useToast } from '~/composables/useToast'
|
||||
|
||||
useHead(() => ({
|
||||
title: 'Nouvelle catégorie de composant',
|
||||
}))
|
||||
|
||||
const router = useRouter()
|
||||
const { showError, showSuccess } = useToast()
|
||||
const saving = ref(false)
|
||||
|
||||
const handleCancel = () => {
|
||||
router.push('/component-category').catch(() => {
|
||||
showError("Navigation impossible vers la liste des catégories.")
|
||||
})
|
||||
}
|
||||
|
||||
const handleSubmit = async (payload: Parameters<typeof createModelType>[0]) => {
|
||||
saving.value = true
|
||||
try {
|
||||
const enrichedPayload = {
|
||||
...payload,
|
||||
description: payload.notes ?? null,
|
||||
}
|
||||
await createModelType(enrichedPayload)
|
||||
showSuccess('Catégorie de composant créée avec succès.')
|
||||
await router.push('/component-category')
|
||||
} catch (error: any) {
|
||||
const message = error?.data?.message || error?.message || 'Une erreur est survenue lors de la création.'
|
||||
showError(Array.isArray(message) ? message[0] : message)
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user