Frontend store API client : - Types StoreInfo (avec slug + isDefault + embedder), StoreDetail, StoreCreatePayload, StoreUpdatePayload - Fonctions createStore (POST), updateStore (PATCH), deleteStore (DELETE), fetchStore (GET /:slug) - Tests Vitest étendus pour les 4 nouveaux endpoints Composants formulaire (features/store/ui/) : - StoreForm : champs communs (name/slug/kind/embedder/isDefault) avec validation slug locale, lock du slug pour 'default' - StoreConfigForm : dispatcher dynamique par kind (extensible) - OpenSearchConfigForm : champ indexName, validation requise Pages CRUD : - StoreCreatePage (/index/new) : formulaire + redirect liste - StoreEditPage (/index/:store/edit) : préremplit via fetchStore, redirige vers la fiche Routes + i18n : - Routes ROUTES.STORE_CREATE et ROUTES.STORE_EDIT ajoutées (names + routes.ts) - Clés i18n FR/EN sous stores.* et storeForm.*
44 lines
934 B
Vue
44 lines
934 B
Vue
<template>
|
|
<component
|
|
:is="component"
|
|
v-model="config"
|
|
:show-error="showError"
|
|
@valid="(v: boolean) => emit('valid', v)"
|
|
/>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue'
|
|
import OpenSearchConfigForm from './OpenSearchConfigForm.vue'
|
|
|
|
const props = defineProps<{
|
|
kind: string
|
|
modelValue: Record<string, unknown>
|
|
showError?: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', value: Record<string, unknown>): void
|
|
(e: 'valid', value: boolean): void
|
|
}>()
|
|
|
|
const config = ref({ ...props.modelValue })
|
|
|
|
watch(config, (next) => emit('update:modelValue', next), { deep: true })
|
|
watch(
|
|
() => props.modelValue,
|
|
(next) => {
|
|
config.value = { ...next }
|
|
},
|
|
{ deep: true },
|
|
)
|
|
|
|
const component = computed(() => {
|
|
switch (props.kind) {
|
|
case 'opensearch':
|
|
return OpenSearchConfigForm
|
|
default:
|
|
return OpenSearchConfigForm
|
|
}
|
|
})
|
|
</script>
|