fix(admin): render visual editor as ui field inside default form
All checks were successful
Build & Deploy to K3s / build-and-deploy (push) Successful in 2m48s
All checks were successful
Build & Deploy to K3s / build-and-deploy (push) Successful in 2m48s
The views.edit.default override replaced Payload's <Form> wrapper, so useField had no form-state context — every field returned undefined and setValue threw "N is not a function" during autosave. Flatten the collection into a single ui field that renders ProductPreviewEditor, with every real field marked admin.hidden:true. The panel now lives inside Payload's default form, so useField gets real values and autosave works. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8f3a26e883
commit
94fdb37dc3
@ -10,15 +10,6 @@ export const Products: CollectionConfig = {
|
||||
useAsTitle: 'productDisplayName',
|
||||
defaultColumns: ['productDisplayName', 'index', 'type', 'price', 'isPublished'],
|
||||
group: 'Contenu',
|
||||
components: {
|
||||
views: {
|
||||
edit: {
|
||||
default: {
|
||||
Component: '@/components/admin/ProductPreviewEditor#default',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
@ -40,183 +31,168 @@ export const Products: CollectionConfig = {
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
label: 'Identité',
|
||||
fields: [
|
||||
{
|
||||
name: 'productDisplayName',
|
||||
label: 'Nom affiché',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { description: 'Le nom visible par le public (ex: Solar Altar)' },
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Nom technique',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { description: 'Nom interne sans espaces (ex: Solar_Altar)' },
|
||||
},
|
||||
{
|
||||
name: 'slug',
|
||||
label: 'URL (slug)',
|
||||
type: 'text',
|
||||
required: true,
|
||||
unique: true,
|
||||
index: true,
|
||||
admin: { description: 'Ex: solar-altar → /collection/solar-altar' },
|
||||
},
|
||||
{
|
||||
name: 'index',
|
||||
label: 'Index projet',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { description: 'Ex: PROJET_001' },
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: 'Type',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { description: 'Ex: LAMPE DE TABLE' },
|
||||
},
|
||||
{
|
||||
name: 'materials',
|
||||
label: 'Matériaux',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'year',
|
||||
label: 'Année',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: '2026',
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: 'Statut',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { description: 'Ex: PROTOTYPE [80%]' },
|
||||
},
|
||||
{
|
||||
name: 'sortOrder',
|
||||
label: 'Ordre d\u2019affichage',
|
||||
type: 'number',
|
||||
defaultValue: 0,
|
||||
},
|
||||
{
|
||||
name: 'isPublished',
|
||||
label: 'Publié',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
},
|
||||
],
|
||||
name: 'previewPanel',
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '@/components/admin/ProductPreviewEditor#default',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'productDisplayName',
|
||||
label: 'Nom affiché',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Nom technique',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'slug',
|
||||
label: 'URL (slug)',
|
||||
type: 'text',
|
||||
required: true,
|
||||
unique: true,
|
||||
index: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'index',
|
||||
label: 'Index projet',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: 'Type',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'materials',
|
||||
label: 'Matériaux',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'year',
|
||||
label: 'Année',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: '2026',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: 'Statut',
|
||||
type: 'text',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'sortOrder',
|
||||
label: 'Ordre d\u2019affichage',
|
||||
type: 'number',
|
||||
defaultValue: 0,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'isPublished',
|
||||
label: 'Publié',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'specs',
|
||||
label: 'Spécifications',
|
||||
type: 'textarea',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
label: 'Notes',
|
||||
type: 'textarea',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'images',
|
||||
label: 'Images',
|
||||
type: 'array',
|
||||
minRows: 1,
|
||||
required: true,
|
||||
admin: { hidden: true },
|
||||
fields: [
|
||||
{
|
||||
label: 'Contenu',
|
||||
fields: [
|
||||
{
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'specs',
|
||||
label: 'Spécifications',
|
||||
type: 'textarea',
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
label: 'Notes',
|
||||
type: 'textarea',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Images',
|
||||
fields: [
|
||||
{
|
||||
name: 'images',
|
||||
label: 'Images',
|
||||
type: 'array',
|
||||
minRows: 1,
|
||||
required: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'image',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Commerce',
|
||||
fields: [
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Prix (en centimes)',
|
||||
type: 'number',
|
||||
admin: {
|
||||
description: '180000 = 1 800 EUR. Vide = non disponible à la vente.',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'currency',
|
||||
label: 'Devise',
|
||||
type: 'select',
|
||||
defaultValue: 'EUR',
|
||||
options: [
|
||||
{ label: 'EUR', value: 'EUR' },
|
||||
{ label: 'USD', value: 'USD' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'availability',
|
||||
label: 'Disponibilité (schema.org)',
|
||||
type: 'select',
|
||||
defaultValue: 'https://schema.org/InStock',
|
||||
options: [
|
||||
{ label: 'En stock', value: 'https://schema.org/InStock' },
|
||||
{ label: 'Disponibilité limitée', value: 'https://schema.org/LimitedAvailability' },
|
||||
{ label: 'Sur commande', value: 'https://schema.org/PreOrder' },
|
||||
{ label: 'Indisponible', value: 'https://schema.org/OutOfStock' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'stripeProductID',
|
||||
type: 'text',
|
||||
admin: {
|
||||
readOnly: true,
|
||||
description: 'Synchronisé automatiquement avec Stripe',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'SEO',
|
||||
fields: [
|
||||
{
|
||||
name: 'seoTitle',
|
||||
label: 'Titre SEO',
|
||||
type: 'text',
|
||||
admin: { description: 'Laissez vide pour utiliser le nom du produit' },
|
||||
},
|
||||
{
|
||||
name: 'seoDescription',
|
||||
label: 'Description SEO',
|
||||
type: 'textarea',
|
||||
},
|
||||
],
|
||||
name: 'image',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Prix (en centimes)',
|
||||
type: 'number',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'currency',
|
||||
label: 'Devise',
|
||||
type: 'select',
|
||||
defaultValue: 'EUR',
|
||||
options: [
|
||||
{ label: 'EUR', value: 'EUR' },
|
||||
{ label: 'USD', value: 'USD' },
|
||||
],
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'availability',
|
||||
label: 'Disponibilité (schema.org)',
|
||||
type: 'select',
|
||||
defaultValue: 'https://schema.org/InStock',
|
||||
options: [
|
||||
{ label: 'En stock', value: 'https://schema.org/InStock' },
|
||||
{ label: 'Disponibilité limitée', value: 'https://schema.org/LimitedAvailability' },
|
||||
{ label: 'Sur commande', value: 'https://schema.org/PreOrder' },
|
||||
{ label: 'Indisponible', value: 'https://schema.org/OutOfStock' },
|
||||
],
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'stripeProductID',
|
||||
type: 'text',
|
||||
admin: { hidden: true, readOnly: true },
|
||||
},
|
||||
{
|
||||
name: 'seoTitle',
|
||||
label: 'Titre SEO',
|
||||
type: 'text',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
{
|
||||
name: 'seoDescription',
|
||||
label: 'Description SEO',
|
||||
type: 'textarea',
|
||||
admin: { hidden: true },
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user