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
24.47k stars 1.55k forks source link

Radio field broken after upgrade #1620

Closed xflysaround closed 1 year ago

xflysaround commented 1 year ago

Bug Report

Upgraded to the latest version 1.2.5 from 1.2.0. Added a radio field to an existing collection and got the following error on page load TypeError: t is not a function.

To be more precise, the error is being thrown in validation.js, the final return line from below

const radio = (value, { t, options, required }) => {
    const stringValue = String(value);
    if ((typeof value !== 'undefined' || !required) && (options.find((option) => String(typeof option !== 'string' && (option === null || option === void 0 ? void 0 : option.value)) === stringValue)))
        return true;
    return t('validation:required');
};

Steps to Reproduce

  1. Add the following to an existing collection:

{ name: 'color', // required type: 'radio', // required options: [ // required { label: 'Mint', value: 'mint', }, { label: 'Dark Gray', value: 'dark_gray', }, ], defaultValue: 'mint', // The first value in options. admin: { layout: 'horizontal', } }

  1. Refresh the page, should get a hard error that blocks page load

Other Details

Same error is occurring with relationship fields when required: true there.

Payload version: 1.2.5. Browser: Chrome.

JarrodMFlesch commented 1 year ago

@xflysaround it sounds like i18next is not installed for you, have you have run yarn after upgrading Payload?

xflysaround commented 1 year ago

@xflysaround it sounds like i18next is not installed for you, have you have run yarn after upgrading Payload?

Yeah, removed node_modules and yarn.lock. In yarn.lock, I see the i18next@^22.0.1.

JarrodMFlesch commented 1 year ago

Interesting! Can you share more of your config?

xflysaround commented 1 year ago

Interesting! Can you share more of your config?

{ "name": "payload-starter-typescript", "description": "Blank template - no collections", "version": "1.0.0", "main": "dist/server.js", "license": "MIT", "scripts": { "dev": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon", "build:payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload build", "build:server": "tsc", "build": "yarn copyfiles && yarn build:payload && yarn build:server", "serve": "cross-env PAYLOAD_CONFIG_PATH=dist/payload.config.js NODE_ENV=production node dist/server.js", "copyfiles": "copyfiles -u 1 \"src/*/.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png}\" dist/", "generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types", "generate:graphQLSchema": "PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.2", "@fortawesome/free-solid-svg-icons": "^6.1.2", "@fortawesome/react-fontawesome": "^0.2.0", "aws-sdk": "^2.1243.0", "core-js-pure": "^3.24.1", "dotenv": "^16.0.1", "express": "^4.17.1", "graphql-request": "^4.3.0", "nanoid": "3.3.4", "node-sass": "^7.0.1", "path": "^0.12.7", "payload": "1.2.5", "prop-types": "^15.8.1", "qs": "^6.11.0", "react-joyride": "^2.5.3", "react-s3-uploader": "^5.0.0", "react-tagsinput": "^3.20.0", "sass-loader": "^13.0.2" }, "devDependencies": { "@types/express": "^4.17.9", "copyfiles": "^2.4.1", "cross-env": "^7.0.3", "nodemon": "^2.0.6", "ts-node": "^9.1.1", "typescript": "^4.1.3", "webpack": "^5.74.0", "webpack-cli": "^4.10.0" } }

JarrodMFlesch commented 1 year ago

@xflysaround Oh I meant your payload config or collection where the radio is not working for you

xflysaround commented 1 year ago

@xflysaround Oh I meant your payload config or collection where the radio is not working for you

Ah sorry about that. Payload Config:

export default buildConfig({
  serverURL: '***',
  telemetry: false,
  admin: {
    user: Users.slug,
    css: path.resolve(__dirname, './styles/appadmin.scss'),
    meta: {
      favicon: favicon,
      ogImage: ogImage
    },
    components: {
      Nav: DefaultNav,
      views: {
        Dashboard: MyCustomDashboard,
      },
      graphics: {
        Icon: Icon,
        Logo: Logo
      },
      routes: [
        {
          Component: Registration,
          path: '/register'
        }
      ]
    },
    webpack: (config) => {
      if (!config.module.rules) {
        config.module.rules = [];
      }
      return config;
    }
  },
  collections: [
    Files,
    Users
  ],
  typescript: {
    outputFile: path.resolve(__dirname, 'payload-types.ts'),
  },
  graphQL: {
    schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
  },
});

Collection:

const Files: CollectionConfig = {
  slug: 'files',
  admin: {
    defaultColumns: ['name', 'size', 'createdAt'],
    disableDuplicate: true,
    listSearchableFields: ['name']
  },
  access: {
    create: isAdmin,
    read: isAdminOrOwner,
    update: isAdminOrOwner,
    delete: isAdminOrOwner,
    unlock: isAdmin
  },
  fields: [
    {
      name: 'users', // required
      type: 'relationship', // required
      relationTo: 'users', // required
      hasMany: false,
      access: {
        update: isAdmin,
      },
      hooks: {
        beforeChange: [
          ({req, value}) => {
            if (req.user) {
              value = req.user.id;
            }
            return value;
          }
        ]
      }
    },
    {
      name: 'color', // required
      type: 'radio', // required
      options: [ // required
        {
          label: 'Mint',
          value: 'mint',
        },
        {
          label: 'Dark Gray',
          value: 'dark_gray',
        },
      ],
      defaultValue: 'mint', // The first value in options.
      admin: {
        layout: 'horizontal',
      }
    },
    {
        name: 'name',
        type: 'text',
        required: true,
        label: 'Name'
    },
    {
      name: 'size',
      type: 'number',
      defaultValue: 0,
      required: false,
      admin: {
        readOnly: true,
        components: {
          Cell: (props) => {
            return formatBytes(props.cellData);
          },
          Field: Size
        }
      }
    }
  ],
  hooks: {
    beforeChange: [
      beforeChangeHook
    ]
  }
}
JarrodMFlesch commented 1 year ago

@xflysaround If you create a new, blank collection and only add the radio field, do you get the same error?

JarrodMFlesch commented 1 year ago

@xflysaround I was unable to recreate this issue using your config and also some of my own. If you can reproduce this with a new project please let me know. I am going to close this for now, but feel free to re-open if you have more information, thanks!

xflysaround commented 1 year ago

@xflysaround I was unable to recreate this issue using your config and also some of my own. If you can reproduce this with a new project please let me know. I am going to close this for now, but feel free to re-open if you have more information, thanks!

Thanks for trying to reproduce.

Works on new collections within the old project. I'm working around it for now on the old collection by supplying my own validate function. So it doesn't ever hit that translate call. Thanks and regards.

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.