Skip to content
This repository has been archived by the owner on Dec 18, 2023. It is now read-only.

TabbedUI breaks content fields with position: 'sidebar' #35

Closed
omavi opened this issue Feb 10, 2023 · 11 comments · Fixed by #47
Closed

TabbedUI breaks content fields with position: 'sidebar' #35

omavi opened this issue Feb 10, 2023 · 11 comments · Fixed by #47

Comments

@omavi
Copy link

omavi commented Feb 10, 2023

The following logic doesn't account for fields that should end up in the sidebar:

plugin-seo/src/index.ts

Lines 82 to 98 in 348b519

const seoFieldsAsTabs: TabsField[] = [{
type: 'tabs',
tabs: [
// if the collection is already tab-enabled, spread them into this new tabs field
// otherwise create a new tab to contain this collection's fields
// either way, append a new tab for the SEO fields
...collection?.fields?.[0].type === 'tabs'
? collection?.fields?.[0]?.tabs : [{
label: collection?.labels?.singular || 'Content',
fields: [...(collection?.fields || [])]
}],
{
label: 'SEO',
fields: seoFields,
}
]
}]

@jacobsfletch
Copy link
Member

@omavi are you saying you have position: 'sidebar' set on your base fields, and those are rendering in the "content" tab instead of the sidebar?

@omavi
Copy link
Author

omavi commented Feb 19, 2023

@jacobsfletch yes, exactly!

@qbeauperin
Copy link

Can confirm, just stumbled upon this issue as well.

@qbeauperin
Copy link

Actually, after looking a bit more into this, I think there's two issues at play here:

  1. A field's admin.position can only be defined if that field is at the first level of the collection's fields array (eg: a field in a Tabs or a Group field will currently not be rendered in the sidebar)
  2. If your first field is a Tabs field, this plugin will discard any other fields defined after this first Tabs field when generating the SEO tab.

@ssyberg
Copy link

ssyberg commented Mar 27, 2023

👍🏼 hitting this too, @qbeauperin I don't totally follow as I'm not explicitly using tabs at all, is there a workaround?

@ssyberg
Copy link

ssyberg commented Mar 27, 2023

Hmm I tried explicitly defining my fields in a "Content" tab and pulling the sidebar fields out of the tabs completely but that resulted in some even stranger behavior:
image

@qbeauperin
Copy link

The workaround I've ended up using is not using the plugin, but using the plugin's fields directly.

import { CollectionConfig } from 'payload/types';

// SEO fields
import { Overview } from '@payloadcms/plugin-seo/dist/ui/Overview';
import { getMetaDescriptionField } from '@payloadcms/plugin-seo/dist/fields/MetaDescription';
import { getMetaTitleField } from '@payloadcms/plugin-seo/dist/fields/MetaTitle';
import { getPreviewField } from '@payloadcms/plugin-seo/dist/ui/Preview';
import { getMetaImageField } from '@payloadcms/plugin-seo/dist/fields/MetaImage';

const seoConfig = {
  uploadsCollection: 'media',
  generateTitle: ({ doc }) => `${doc?.title?.value} — Site name`,
  generateDescription: ({ doc }) => doc?.excerpt?.value,
  generateURL: ({ doc }) => `https://faefarm.com/news/${doc?.slug?.value}`,
  generateImage: ({ doc }) => doc?.featuredImage?.value,
}

const Posts: CollectionConfig = {
  slug: 'posts',
  fields: [
    {
      type: 'tabs',
      tabs: [
        {
          label: 'Content',
          fields: [
            {
              name: 'title',
              type: 'text',
              localized: true,
              required: true,
            },
            {
              name: 'slug',
              type: 'text',
              localized: true,
              required: true,
              unique: true,
            },
            {
              name: 'content',
              type: 'richText',
              localized: true,
            },
          ]
        },
        {
          label: 'SEO',
          fields: [
            {
              name: 'meta',
              label: 'SEO',
              type: 'group',
              fields: [
                {
                  name: 'overview',
                  label: 'Overview',
                  type: 'ui',
                  admin: {
                    components: {
                      Field: Overview,
                    },
                  },
                },
                {
                  name: 'title',
                  type: 'text',
                  localized: true,
                  admin: {
                    components: {
                      Field: (props) => getMetaTitleField({ ...props, ...{ pluginConfig: seoConfig } }),
                    },
                  },
                },
                {
                  name: 'description',
                  type: 'textarea',
                  localized: true,
                  admin: {
                    components: {
                      Field: (props) => getMetaDescriptionField({ ...props, ...{ pluginConfig: seoConfig } }),
                    },
                  },
                },
                {
                  name: 'image',
                  label: 'Meta Image',
                  type: 'upload',
                  localized: true,
                  relationTo: seoConfig?.uploadsCollection,
                  admin: {
                    description: 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',
                    components: {
                      Field: (props) => getMetaImageField({ ...props, ...{ pluginConfig: seoConfig } }),
                    },
                  },
                },
                {
                  name: 'preview',
                  label: 'Preview',
                  type: 'ui',
                  admin: {
                    components: {
                      Field: (props) => getPreviewField({ ...props, ...{ pluginConfig: seoConfig } }),
                    },
                  },
                },
              ]
            }
          ]
        }
      ]
    },
    {
      name: 'publishedDate',
      type: 'date',
      admin: {
        position: 'sidebar',
      },
    },
  ],
}

export default Posts;

@ssyberg
Copy link

ssyberg commented Apr 5, 2023

I implemented a workaround in a separate plugin that moves all sidebar fields to the top of CollectionConfig.fields

@jacobsfletch
Copy link
Member

Actually, after looking a bit more into this, I think there's two issues at play here:

  1. A field's admin.position can only be defined if that field is at the first level of the collection's fields array (eg: a field in a Tabs or a Group field will currently not be rendered in the sidebar)
  2. If your first field is a Tabs field, this plugin will discard any other fields defined after this first Tabs field when generating the SEO tab.

@qbeauperin you are spot on here, I just opened PR #47 with the fix. I've also updated the README and any relevant code with notes explaining exactly what tabbedUI does to your config and how to render fields outside the tabs. Here's the gist:

If your collection is not already tab-enabled, meaning the first field in your config is not of type tabs, then one will be created for you called Content. If you wish to continue to use top-level or sidebar fields with tabbedUI, you must not let the default Content tab get created for you. Instead, you must define the first field of your config with type tabs and place all other fields adjacent to this one at the top-level. There's an example of that here.

THANK YOU everyone for your patience on this. It looks like we've had a handle of others waiting on this fix, too. I'll report back as soon as possible, as soon as a release has been published.

@jacobsfletch
Copy link
Member

Just shipped in v1.0.12 🚀

@omavi
Copy link
Author

omavi commented May 21, 2023

Thanks @jacobsfletch! Just made the changes and they're working well 😌

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants