payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
25.64k stars 1.63k forks source link

Group Field Level Localisation #8681

Closed miller-design closed 1 month ago

miller-design commented 1 month ago

Link to reproduction

No response

Describe the Bug

Environment info

payload: '^2.28.0' npm: '10.8.2', node: '20.17.0'

Describe the Bug

When trying to set up translatable fields i was getting an issue where data from the translatable fields were not being saved correctly, i was having issues with content being deleted or overwritten. The issue seemed to boil down to setting the localised option on a group field rather than each individual field in that group like so:

{
  name: "attract_title",
  label: "Attract Title",
  type: "group",
  fields: [
    {
      name: 'line_one',
      label: 'First Line',
      type: 'text',
      localized: true,
    },
    {
      name: 'line_two',
      label: 'Second Line',
      type: 'text',
      localized: true,
    }
  ]
}

This field was at the start of the collection and then proceeded to have knock on effects and preventing other fields from saving correctly.

When following the payload docs to set up all the necessary steps i came across this message:

Note: Enabling localization for field types that support nested fields will automatically create localized "sets" of all fields contained within the field. For example, if you have a page layout using a blocks field type, you have the choice of either localizing the full layout, by enabling localization on the top-level blocks field, or only certain fields within the layout. - link to doc here

Screen recording of the bug https://github.com/user-attachments/assets/eb6b4a9f-0183-46cf-8c36-8cedd4f8a54c

To Reproduce

Set up your payload config with localization:

localization: {
    locales: [
      { label: "English", code: "en" },
      { label: "French", code: "fr" },
      { label: "Deutsch", code: "de" },
      { label: "Arabic", code: "ar" },
      { label: "Japanese", code: "ja" },
      { label: "Chinese", code: "zh" },
      { label: "Korean", code: "ko" },
      { label: "Taiwan Chinese", code: "zh-tw" },
    ],
    defaultLocale: "en",
    fallback: true,
  },

next set up a collection

const Campaigns: CollectionConfig = {
  slug: 'campaigns',
  labels: {
    singular: "Campaign",
    plural: "Campaigns",
  },
  admin: {
    useAsTitle: 'title',
    group: "Campaign Information",
    defaultColumns: ['title'],
    hooks: {
      beforeDuplicate: async ({ data }) => {
        console.log(data)
        return {
          ...data,
          title: `${data.title} (Copy)`,
          general: {
            ...data.general,
            linked_stock_levels: []
          }
        }
      },
    },
  },
  fields: [
    {
      name: "title",
      label: "Title",
      type: "text",
    },
    {
      type: 'tabs',
      tabs: [
        {
          name: 'content',
          label: 'Content',
          fields: [
            {
              name: "attract_title",
              label: "Attract Title",
              type: "group",
              localized: true,
              fields: [
                {
                  name: 'line_one',
                  label: 'First Line',
                  type: 'text',
                },
                {
                  name: 'line_two',
                  label: 'Second Line',
                  type: 'text',
                }
              ]
            },
            {
              type: 'row',
              fields: [
                {
                  name: "attract_asset",
                  label: "Attract Asset",
                  type: "json",
                  localized: true,
                  admin: {
                    components: {
                      Field: CloudinaryMediaUpload,
                    },
                    width: "50%",
                  },
                },
                {
                  name: "attract_background_asset",
                  label: "Attract Background Asset",
                  type: "json",
                  admin: {
                    components: {
                      Field: CloudinaryMediaUpload,
                    },
                    width: "50%",
                  },
                },
              ]
            },
            {
              name: 'highlight_color',
              label: 'Highlight Color',
              type: 'text',
              admin: {
                description: 'Please input the hex code for the colour you want to use.'
              }
            },
            {
              type: 'row',
              fields: [
                {
                  name: 'colour_mode',
                  label: 'Set Dark Mode',
                  type: 'checkbox',
                  defaultValue: false,
                },
                {
                  name: 'logo_colour',
                  label: 'Make Logo White',
                  type: 'checkbox',
                  defaultValue: false,
                },
              ]
            },
            {
              name: "no_win_asset",
              label: "No Win Asset",
              type: "json",
              localized: true,
              admin: {
                components: {
                  Field: CloudinaryMediaUpload,
                },
                width: "33.33%",
              },
            },
            {
              name: 'show_disclaimer',
              label: 'Show Disclaimer',
              type: 'checkbox',
              localized: true,
            },
            {
              name: 'disclaimer',
              label: 'Disclaimer',
              type: 'textarea',
              localized: true,
              admin: {
                condition: (data) => {
                  if (data?.content?.show_disclaimer) {
                    return true
                  } else {
                    return false
                  }
                },
              }
            },
            {
              name: 'show_claim_instructions',
              label: 'Show Claim Instructions',
              type: 'checkbox',
              localized: true,
            },
            {
              name: 'claim_instructions',
              label: 'Claim Instructions',
              type: 'textarea',
              localized: true,
              admin: {
                condition: (data) => {
                  if (data.content?.show_claim_instructions) {
                    return true
                  } else {
                    return false
                  }
                },
              }
            },
          ]
        },
      ]
    }
  ],
}

export default Campaigns

Payload Version

2.28.0

Adapters and Plugins

db-postgres v0.8.5

r1tsuu commented 1 month ago

Hey @miller-design, we know this issue and it's already fixed in 3.0. And actually, we got merged this huge PR https://github.com/payloadcms/payload/pull/8468 that ports many fixes, including this. I don't have info when we can release that, but it should be soon.

miller-design commented 1 month ago

Hey @r1tsuu, I had saw some similar issues relating to V3 just couldn't find anywhere where it was flagged for V2. Thanks for the update and ill keep an eye out for when this PR is released.

github-actions[bot] commented 1 month ago

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.