Running the demo

default discord avatar
SuddenDev
2 years ago
1 5

Hello again,
as I'm digging deeper into payload, I was wondering on how to setup custom components for

  1. The Dashboard / UI and
  2. Custom fieldtypes

The documentation is a bit scarce on that imo, so I wanted to run the demo project but whenever I clone the repo and run npm run build or npm run demo I get errors.


> payload@0.4.4 build
> yarn copyfiles && yarn build:tsc && yarn build:components

yarn run v1.22.4
$ copyfiles -u 1 src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png} dist/
✨  Done in 0.58s.
yarn run v1.22.4
$ tsc --p tsconfig.admin.json && tsc --p tsconfig.server.json
src/admin/hooks/useUnmountEffect.tsx:4:78 - error TS2345: Argument of type '() => React.EffectCallback' is not assignable to parameter of type 'EffectCallback'.
  Type 'EffectCallback' is not assignable to type 'void | Destructor'.
    Type 'EffectCallback' is not assignable to type 'Destructor'.
      Type 'void | Destructor' is not assignable to type 'void | { [UNDEFINED_VOID_ONLY]: never; }'.
        Type 'Destructor' is not assignable to type 'void | { [UNDEFINED_VOID_ONLY]: never; }'.
          Property '[UNDEFINED_VOID_ONLY]' is missing in type 'Destructor' but required in type '{ [UNDEFINED_VOID_ONLY]: never; }'.

4 const useUnmountEffect = (callback: React.EffectCallback): void => useEffect(() => callback, []);
                                                                               ~~~~~~~~~~~~~~

  node_modules/@types/react/index.d.ts:58:34
    58 type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
                                        ~~~~~~~~~~~~~~~~~~~~~
    '[UNDEFINED_VOID_ONLY]' is declared here.
  src/admin/hooks/useUnmountEffect.tsx:4:78
    4 const useUnmountEffect = (callback: React.EffectCallback): void => useEffect(() => callback, []);
                                                                                   ~~~~~~~~~~~~~~
    Did you mean to call this expression?

src/admin/index.tsx:21:27 - error TS2741: Property 'xl' is missing in type '{ xs: number; s: number; m: number; l: number; }' but required in type 'Breakpoints'.

21       <WindowInfoProvider breakpoints={{
                             ~~~~~~~~~~~

  node_modules/@faceless-ui/window-info/dist/WindowInfoProvider/types.d.ts:6:5
    6     xl: number;
          ~~
    'xl' is declared here.
  node_modules/@faceless-ui/window-info/dist/WindowInfoProvider/types.d.ts:9:5
    9     breakpoints: Breakpoints;
          ~~~~~~~~~~~
    The expected type comes from property 'breakpoints' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<WindowInfoProvider> & Readonly<Props> & Readonly<...>'

src/uploads/getFileByPath.ts:9:27 - error TS2339: Property 'getType' does not exist on type 'typeof import("/Users/dominik/Development/payload/node_modules/@types/mime/index")'.

9     const mimetype = mime.getType(filePath);
                            ~~~~~~~


Found 3 errors.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
npm ERR! code 2
npm ERR! path /Users/dominik/Development/payload
npm ERR! command failed
npm ERR! command sh -c yarn copyfiles && yarn build:tsc && yarn build:components

npm ERR! A complete log of this run can be found in:

So my question is: How are you supposed to run the demo? Does someone have a writeup?

  • discord user avatar
    DanRibbens
    Payload Team
    2 years ago

    Hi @SuddenDev,
    We use the demo in the repo as our develepment playground when building new features or troubleshooting. It could be useful for reference, but it might not provide a ton of value for building your own projects with Payload as your dependency. You're welcome to play with it though! You can use npm run dev for live reload or demo:build will create a dist of the demo in /dist/bin/.

    I'm not certain about the errors you shared, we use yarn build when its time to release each new version of Payload. I am not sure how useful that would be for you.

    Have you read the docs part about customizing components? https://payloadcms.com/docs/admin/components#fields

    Certainly there is more we can provide when it comes to custom fields, what is it you're looking to do? I'm happy to help!

    5 replies
  • default discord avatar
    SuddenDev
    2 years ago

    Hi @DanRibbens,
    Ah, that's good to know! I thought the demo was also build-able by users, since it's referenced in the docs.

    I did read through the documentation, but have a bit of a trouble to wrap my head around it. Maybe it's just me, but an written example guide would be a great addition to the (already good) docs.

    • So let's just assume that I need a color picker field. How would you start with that? Can you register the the field globally or do you have to reference it in every collection / global, that you need it in?
    • And as far as I understood it, Filter and Cell are just for the Listview in the panel and don't really need logic in my colorpicker example, since it would just render some stuff (e.g. the hex code), right?

    I'd highly appreacate it, if you could give like even just a short tutorial or write up!

  • discord user avatar
    DanRibbens
    Payload Team
    2 years ago

    We will have more tutorials up in the future. I'm going to add this to our list topics to cover in more depth. For now I'll do my best to answer your questions.

    What I would recommend is if you have a field that you want to reuse throughout your collections or globals, export it from a single place in your app.

    filename: colorField.js

    // assuming these are actual components in your app somewhere
    import ColorPicker from '../components/ColorPicker';
    import ColorChip from '../components/ColorChip';
    
    // let's validate colors just in case
    function isHexColor(val) {
      return val.match(/^#(?:[0-9a-fA-F]{3}){1,2}$/) || `${val} is not a valid hex color`;
    }
    
    const colorField = {
          name: 'color',
          label: 'Color',
          type: 'text',
          validate: (val) => isHexColor(val),
          admin: {
            components: {
              Field: ColorPicker,
              Cell: ColorChip,
            },
          },
        };
    export default colorField;

    Then in your collection that uses the color:
    filename: Users.js

    import colorField from '../fields/colorField';
    
    // optionally you use colorField in your fields array unmodified, this is an example of re-use with collection specific changes
    const favoriteColor =  { 
      name: 'favoriteColor',
      label: 'Favorite Color',
      ...colorField
      };
    
    const Users = {
      slug: 'users',
      auth: true,
      admin: {
        useAsTitle: 'email',
      },
      fields: [
        {
          name: "email",
          label: "Email",
          type: "email",
        },
        favoriteColor,
      ]
    };
    
    export default Users;

    Nothing fancy going on here, pretty much just writing javascript. The Payload backend needs to understand the type but other than that you can do what you want. My example hopefully gives some ideas about structuring your app and keeping it DRY if you plan to reuse a field.

    You're right about Filter and Cell components these are presentational in the admin UI and nothing more.

  • default discord avatar
    SuddenDev
    2 years ago

    Hi @DanRibbens,
    thank you so much for the writeup! That makes it a lot more clear now. I somehow thought it would be more difficult, but that actually very straight forward!
    Can't wait to start digging in, when I actually need a custom field component.

  • discord user avatar
    DanRibbens
    Payload Team
    2 years ago

    I mentioned Cell is presentational only, but there are use cases where you would do something dynamic or add functionality right in the table with an action button or dropdown menu that fires an API call to modify that item.
    You could have a Cell for a status field that shows as a dropdown that calls the API to update it on change as an example.

  • discord user avatar
    DanRibbens
    Payload Team
    2 years ago

    We published a blog post that covers how to implement custom fields. Posting here for visibility:
    https://payloadcms.com/blog/building-a-custom-field

  • default discord avatar
    SuddenDev
    2 years ago

    So I just tried a couple of things with the config. Replacing the Nav was easy, but I got an error when trying to replace views.dashboard. The error code says "not allowed".

    My code:

    import path from "path";
    import React from "react";
    
    import { buildConfig } from "payload/config";
    import Pages from "./collections/Pages";
    import Portfolio from "./collections/Portfolio";
    import Users from "./collections/Users";
    import Upload from "./collections/Upload";
    
    export default buildConfig({
      serverURL: "http://localhost:3000",
      admin: {
        user: Users.slug,
        indexHTML: path.resolve(__dirname, "./client/index.html"),
        components: {
          views: {
            Dashboard: () => <div>Hello</div>,
          },
        },
      },
      collections: [Pages, Portfolio, Users, Upload],
      localization: {
        locales: ["en", "de"],
        defaultLocale: "en",
        fallback: true,
      },
    });
    

    My console:

    [nodemon] restarting due to changes...
    [nodemon] starting `node server.js`
    [23:33:32] INFO (payload): Starting Payload...
    [23:33:33] ERROR (payload): There were 1 errors validating your Payload config
    [23:33:33] ERROR (payload): 1: "admin.components.views" is not allowed
    [nodemon] app crashed - waiting for file changes before starting...
    

    Any Ideas? Did I miss something?

    2 replies
    discord user avatar
    DanRibbens
    Payload Team
    2 years ago

    Hi again,

    That looks to be a bug with our validation. I'll open an issue so we can get it patched.

    edit
    This is now closed. #94 and I've published the change in Payload v0.4.5.

    default discord avatar
    SuddenDev
    2 years ago

    Wow, you guys are really quick. Thanks for the quick bugfix!
    Cheers!

  • default discord avatar
    ssyberg
    last year

    Hi there, I'm also interested in playing with the demo / sandbox but haven't had any luck starting it up - any ideas?

    > payload@0.13.6 dev
    > cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts nodemon
    
    [nodemon] 2.0.15
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): src/**/*.ts demo/**/*
    [nodemon] watching extensions: ts,js,json
    [nodemon] starting `node ./demo/index.js`
    [17:20:24] INFO (payload): Starting Payload...
    node:internal/modules/cjs/loader:944
      throw err;
      ^
    
    Error: Cannot find module '../dist/admin/components/forms/Form/context'
    Require stack:
    - /Users/seth/dev/payload/payload/components/forms.ts
    - /Users/seth/dev/payload/payload/demo/collections/CustomComponents/components/fields/Group/Field/index.tsx
    - /Users/seth/dev/payload/payload/demo/collections/CustomComponents/index.ts
    - /Users/seth/dev/payload/payload/demo/payload.config.ts
    - /Users/seth/dev/payload/payload/src/config/load.ts
    - /Users/seth/dev/payload/payload/src/index.ts
    - /Users/seth/dev/payload/payload/demo/server.ts
    - /Users/seth/dev/payload/payload/demo/index.js
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:941:15)
        at Function.Module._load (node:internal/modules/cjs/loader:774:27)
        at Module.require (node:internal/modules/cjs/loader:1013:19)
        at require (node:internal/modules/cjs/helpers:93:18)
        at Object.<anonymous> (/Users/seth/dev/payload/payload/components/forms.ts:1:2008)
        at Module._compile (node:internal/modules/cjs/loader:1109:14)
        at Module._compile (/Users/seth/dev/payload/payload/node_modules/pirates/lib/index.js:99:24)
        at Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
        at Object.newLoader [as .ts] (/Users/seth/dev/payload/payload/node_modules/pirates/lib/index.js:104:7)
        at Module.load (node:internal/modules/cjs/loader:989:32) {
      code: 'MODULE_NOT_FOUND',
      requireStack: [
        '/Users/seth/dev/payload/payload/components/forms.ts',
        '/Users/seth/dev/payload/payload/demo/collections/CustomComponents/components/fields/Group/Field/index.tsx',
        '/Users/seth/dev/payload/payload/demo/collections/CustomComponents/index.ts',
        '/Users/seth/dev/payload/payload/demo/payload.config.ts',
        '/Users/seth/dev/payload/payload/src/config/load.ts',
        '/Users/seth/dev/payload/payload/src/index.ts',
        '/Users/seth/dev/payload/payload/demo/server.ts',
        '/Users/seth/dev/payload/payload/demo/index.js'
      ]
    }
    [nodemon] app crashed - waiting for file changes before starting...
    
    
  • default discord avatar
    ssyberg
    last year

    ☝🏼 seems like there's dependency on a build for yarn dev so I tried demo:build first:

    yarn demo:build         
    yarn run v1.22.17
    $ cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts node dist/bin/build
    node:internal/modules/cjs/loader:944
      throw err;
      ^
    
    Error: Cannot find module '/Users/seth/dev/payload/payload/dist/bin/build'
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:941:15)
        at Function.Module._load (node:internal/modules/cjs/loader:774:27)
        at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
        at node:internal/main/run_main_module:17:47 {
      code: 'MODULE_NOT_FOUND',
      requireStack: []
    }
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
    
  • default discord avatar
    ssyberg
    last year

    NM I'm up and running, needed to just yarn build first.

    1 reply
    discord user avatar
    jmikrut
    Payload Team
    last year

    Hey @ssyberg — yep. Good catch! We're actually re-wiring some things so that soon, you won't need to yarn build before running demo, but for now, that's how it works.

    Will be improved shortly. Let us know if you have any questions as you poke around!

Open the post
Continue the discussion in GitHub
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.