Files
payload/test/plugin-import-export/collections/Pages.ts
Patrik 8f85da8931 fix(plugin-import-export): json preview and downloads preserve nesting and exclude disabled fields (#13210)
### What?

Improves both the JSON preview and export functionality in the
import-export plugin:
- Preserves proper nesting of object and array fields (e.g., groups,
tabs, arrays)
- Excludes any fields explicitly marked as `disabled` via
`custom.plugin-import-export`
- Ensures downloaded files use proper JSON formatting when `format` is
`json` (no CSV-style flattening)

### Why?

Previously:
- The JSON preview flattened all fields to a single level and included
disabled fields.
- Exported files with `format: json` were still CSV-style data encoded
as `.json`, rather than real JSON.

### How?

- Refactored `/preview-data` JSON handling to preserve original document
shape.
- Applied `removeDisabledFields` to clean nested fields using
dot-notation paths.
- Updated `createExport` to skip `flattenObject` for JSON formats, using
a nested JSON filter instead.
- Fixed streaming and buffered export paths to output valid JSON arrays
when `format` is `json`.
2025-07-24 11:36:46 -04:00

241 lines
5.1 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import { pagesSlug } from '../shared.js'
export const Pages: CollectionConfig = {
slug: pagesSlug,
labels: {
singular: { en: 'Page', es: 'Página' },
plural: { en: 'Pages', es: 'Páginas' },
},
admin: {
useAsTitle: 'title',
},
versions: {
drafts: true,
},
fields: [
{
name: 'title',
label: { en: 'Title', es: 'Título', de: 'Titel' },
type: 'text',
required: true,
},
{
name: 'localized',
type: 'text',
localized: true,
},
{
name: 'custom',
type: 'text',
defaultValue: 'my custom csv transformer',
custom: {
'plugin-import-export': {
toCSV: ({ value, columnName, row, siblingDoc }) => {
return String(value) + ' toCSV'
},
},
},
},
{
name: 'customRelationship',
type: 'relationship',
relationTo: 'users',
custom: {
'plugin-import-export': {
toCSV: ({ value, columnName, row }) => {
if (value && typeof value === 'object' && 'id' in value && 'email' in value) {
row[`${columnName}_id`] = (value as { id: number | string }).id
row[`${columnName}_email`] = (value as { email: string }).email
}
},
},
},
},
{
name: 'group',
type: 'group',
fields: [
{
name: 'value',
type: 'text',
defaultValue: 'group value',
// custom: {
// 'plugin-import-export': {
// disabled: true,
// },
// },
},
{
name: 'ignore',
type: 'text',
},
{
name: 'array',
type: 'array',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
],
},
{
name: 'custom',
type: 'text',
defaultValue: 'my custom csv transformer',
custom: {
'plugin-import-export': {
toCSV: ({ value, columnName, row, siblingDoc, doc }) => {
return String(value) + ' toCSV'
},
},
},
},
],
},
{
type: 'tabs',
tabs: [
{
label: 'No Name',
fields: [
{
name: 'tabToCSV',
type: 'text',
defaultValue: 'my custom csv transformer',
custom: {
'plugin-import-export': {
toCSV: ({ value, columnName, row, siblingDoc, doc }) => {
return String(value) + ' toCSV'
},
},
},
},
],
},
{
name: 'namedTab',
fields: [
{
name: 'tabToCSV',
type: 'text',
defaultValue: 'my custom csv transformer',
custom: {
'plugin-import-export': {
toCSV: ({ value, columnName, row, siblingDoc, doc }) => {
return String(value) + ' toCSV'
},
},
},
},
],
},
],
},
{
name: 'array',
type: 'array',
fields: [
{
name: 'field1',
type: 'text',
},
{
name: 'field2',
type: 'text',
},
],
},
{
name: 'blocks',
type: 'blocks',
blocks: [
{
slug: 'hero',
fields: [
{
name: 'title',
type: 'text',
},
],
},
{
slug: 'content',
fields: [
{
name: 'richText',
type: 'richText',
},
],
},
],
},
{
name: 'author',
type: 'relationship',
relationTo: 'users',
},
{
name: 'virtualRelationship',
type: 'text',
virtual: 'author.name',
},
{
name: 'virtual',
type: 'text',
virtual: true,
hooks: {
afterRead: [() => 'virtual value'],
},
},
{
name: 'hasManyNumber',
type: 'number',
hasMany: true,
},
{
name: 'relationship',
type: 'relationship',
relationTo: 'users',
},
{
name: 'excerpt',
label: 'Excerpt',
type: 'text',
},
{
name: 'hasOnePolymorphic',
type: 'relationship',
relationTo: ['users', 'posts'],
hasMany: false,
},
{
name: 'hasManyPolymorphic',
type: 'relationship',
relationTo: ['users', 'posts'],
hasMany: true,
},
{
type: 'collapsible',
label: 'Collapsible Field',
fields: [
{
name: 'textFieldInCollapsible',
type: 'text',
// custom: {
// 'plugin-import-export': {
// disabled: true,
// },
// },
},
],
},
],
}