keystonejs / keystone

The superpowered headless CMS for Node.js — built with GraphQL and React
https://keystonejs.com
MIT License
9.22k stars 1.16k forks source link

Custom pages not rendering and TypeScript error for 'pages' property in UI configuration #9362

Open mattbylett opened 6 days ago

mattbylett commented 6 days ago

Description

I'm trying to add a custom page to the Keystone 6 Admin UI, but I'm encountering two issues:

  1. The custom page is not rendering (404 error when accessing it).
  2. TypeScript is throwing an error about the pages property in the UI configuration.

Steps to Reproduce

  1. Create a new Keystone 6 project:

    mkdir keystone-custom-page-test
    cd keystone-custom-page-test
    npm init -y
    npm install @keystone-6/core @keystone-6/auth
  2. Create the following files:

    keystone.ts:

    import { config } from '@keystone-6/core';
    import { lists } from './schema';
    import { withAuth, session } from './auth';
    import path from 'path';
    
    export default withAuth(
     config({
       db: {
         provider: 'sqlite',
         url: 'file:./keystone.db',
       },
       lists,
       session,
       ui: {
         isAccessAllowed: (context) => !!context.session?.data,
         getAdditionalFiles: [
           async () => [
             {
               mode: 'write',
               src: `
                 import CustomPage from '${path.resolve(__dirname, './admin/pages/custom-page')}';
                 export default CustomPage;
               `,
               outputPath: 'custom.js',
             },
           ],
         ],
         pages: () => [
           {
             label: "Custom Page",
             path: "custom",
             component: path.resolve(__dirname, "./admin/pages/custom-page"),
           },
         ],
       },
     })
    );

    schema.ts:

    import { list } from '@keystone-6/core';
    import { text, password } from '@keystone-6/core/fields';
    
    export const lists = {
     User: list({
       access: {
         operation: {
           query: ({ session }) => !!session,
           create: ({ session }) => !!session,
           update: ({ session }) => !!session,
           delete: ({ session }) => !!session,
         },
       },
       fields: {
         name: text({ validation: { isRequired: true } }),
         email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
         password: password({ validation: { isRequired: true } }),
       },
     }),
    };

    auth.ts:

    import { createAuth } from '@keystone-6/auth';
    import { statelessSessions } from '@keystone-6/core/session';
    
    const { withAuth } = createAuth({
     listKey: 'User',
     identityField: 'email',
     sessionData: 'name',
     secretField: 'password',
     initFirstItem: {
       fields: ['name', 'email', 'password'],
     },
    });
    
    const sessionSecret = '-- DEV COOKIE SECRET; CHANGE ME --';
    const sessionMaxAge = 60 * 60 * 24 * 30; // 30 days
    
    const session = statelessSessions({
     maxAge: sessionMaxAge,
     secret: sessionSecret,
    });
    
    export { withAuth, session };

    admin/pages/custom-page.tsx:

    import React from 'react';
    import { PageContainer } from '@keystone-6/core/admin-ui/components';
    
    export default function CustomPage() {
     return (
       <PageContainer header="Custom Page">
         <h1>This is a custom admin page</h1>
       </PageContainer>
     );
    }
  3. Run npm run dev

Expected Behavior

  1. The custom page should be accessible at http://localhost:3000/custom
  2. There should be no TypeScript errors related to the pages property

Actual Behavior

  1. Accessing http://localhost:3000/custom results in a 404 error
  2. TypeScript throws the following error:

    Object literal may only specify known properties, and 'pages' does not exist in type '{ isDisabled?: boolean | undefined; isAccessAllowed?: ((context: KeystoneContext<any>) => MaybePromise<boolean>) | undefined; publicPages?: readonly string[] | undefined; basePath?: string | undefined; getAdditionalFiles?: readonly (() => MaybePromise<...>)[] | undefined; pageMiddleware?: ((args: { ...; }) => MaybeP...'.ts(2353)
    index.d.ts(184, 5): The expected type comes from property 'ui' which is declared here on type 'KeystoneConfig<any>'
    (property) pages: () => {
       label: string;
       path: string;
       component: string;
    }[]

Environment

Additional Context

This issue occurs in a clean installation of Keystone 6, suggesting it's not related to any specific project configuration.

marekryb commented 5 days ago

As the error clearly says, ui.pages option does not exist. Where did you take that code from?

See relevant example https://github.com/keystonejs/keystone/tree/main/examples/custom-admin-ui-pages

mattbylett commented 4 days ago

Ok thank you for the documentation link - my mistake

apologies for wasting your time

On Tue, 15 Oct 2024 at 19:31, Marek R @.***> wrote:

As the error clearly says, ui.pages option does not exist. Where did you take that code from?

See relevant example https://github.com/keystonejs/keystone/tree/main/examples/custom-admin-ui-pages

— Reply to this email directly, view it on GitHub https://github.com/keystonejs/keystone/issues/9362#issuecomment-2413006873, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHNVISMPGDQE3GIG4SKJPHDZ3SZELAVCNFSM6AAAAABP4HNK3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJTGAYDMOBXGM . You are receiving this because you authored the thread.Message ID: @.***>