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
22.01k stars 1.33k forks source link

path to custom Field in type block not resolved as expected #6650

Closed genox closed 1 month ago

genox commented 1 month ago

Link to reproduction

No response

Payload Version

beta40

Node Version

20

Next.js Version

15rc0

Describe the Bug

I have a block that looks like this:

import { Block } from 'payload/types';
import { GraphInputField } from '@/components/graph/Input/graph-input-field';
import { GraphTaskField } from '@/components/graph/Input/graph-task-field';
import { translations } from '@/lib/translations';
import './block.scss';

export const StartBlock: Block = {
  slug: 'block-start',
  imageURL: '/process-block-shapes/block-start.svg',
  imageAltText: 'Start of a process',
  fields: [
    {
      type: 'row',
      admin: {
        className: 'process-block-row',
      },
      fields: [
        {
          type: 'group',
          name: 'graph',
          label: false,
          admin: {
            className: 'graph-fields-group',
          },
          fields: [
            {
              type: 'row',
              admin: {
                className: 'graph-fields-row',
              },
              fields: [
                {
                  name: 'first',
                  type: 'textarea',
                  admin: {
                    components: {
                      Field: GraphInputField,
                    },
                  },
                },
                {
                  name: 'second',
                  type: 'textarea',
                  admin: {
                    components: {
                      Field: GraphTaskField,
                    },
                  },
                },
              ],
            },
          ],
        },
        {
          type: 'tabs',
          tabs: [
            {
              name: 'keypoints-tab',
              label: translations.fieldLabel.keypoints,
              fields: [
                {
                  name: 'keypoints',
                  label: false,
                  type: 'richText',
                },
              ],
            },
            {
              name: 'tools-tab',
              label: translations.fieldLabel.tools,
              fields: [
                {
                  name: 'tools',
                  label: false,
                  type: 'richText',
                },
              ],
            },
            {
              name: 'responsibility-tab',
              label: translations.fieldLabel.responsibility,
              fields: [
                {
                  name: 'responsibility',
                  label: false,
                  type: 'richText',
                },
              ],
            },
          ],
        },
      ],
    },
  ],
};

path via useField() in GraphInputField and GraphTaskField looks like this :

fragment.block-start..graph..first

fragment is the array holding the blocks.

it looks like the path name generator fails to generate a proper path for the custom ui fields making it impossible to save the data entered.

When I remove the custom components and instead use regular type: textarea, saving works just fine.

Both custom components look like this:

'use client';
import { useField } from '@payloadcms/ui/forms/useField';
import { LineVertical } from '@/components/graph/connectors/line-vertical';
import { ArrowDown } from '@/components/graph/connectors/arrow-down';
import { TaskWrapper } from '@/components/graph/wrappers/task-wrapper';
import { logger } from '@/lib/logger';

export const GraphTaskField: React.FC<{ path: string }> = ({ path }) => {
  const { value, setValue } = useField<string>({ path });
  logger.info('GraphTaskField', { path, value });
  return (
    <div className={'flex flex-col'} style={{ paddingLeft: 0 }}>
      <TaskWrapper>
        <textarea
          className={ 'textarea-l size-full text-center focus:outline-none' }
          onChange={(e) => setValue(e.target.value)}
          value={value}
        />
      </TaskWrapper>
      <div className={'flex grow flex-col items-center justify-center'}>
        <LineVertical />
        <ArrowDown />
      </div>
    </div>
  );
};

This should work, no?

I can't say if this is a bug or wether I am doing something wrong.

Reproduction Steps

Adapters and Plugins

No response

JarrodMFlesch commented 1 month ago

@genox this will be fixed in the next release.

Related PR

genox commented 1 month ago

@JarrodMFlesch Thank you!

genox commented 1 month ago

@JarrodMFlesch I noticed that this issue possibly regressed in beta.54 or 53.

I used

  const { path } = useFieldProps();

to get the path value as suggested by Paul on discord but this is undefined now. Is this supposed to be undefined?