adminjs-nestjs
adminjs-nestjs copied to clipboard
Provide a more explanatory example project
Hi, thanks for your work.
I spent hours trying to customise a property in the list without any success, and I'd like some pointers.
My project uses
- nest.js
- typescript
- adminBro
I'm following the docs to the letter. In the configuration I added:
{ resource: styleModel, options: {
properties: {
parentId: {
components: {
list: AdminBro.bundle('./components/reference-in-list'),
},
}
}
} },
My ./components/reference-in-list is defined as the following:
import React from 'react'
import { InputGroup, Label } from '@admin-bro/design-system'
import { BasePropertyProps } from 'admin-bro'
const ReferenceInList: React.FC<BasePropertyProps> = (props) => {
const { record, property } = props
const value = record.params[property.name]
return (
<InputGroup>
<Label>{property.name}</Label>
{value}
</InputGroup>
)
}
export default ReferenceInList
All I got is an error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Is there any special configuration to add when using adminBro with nest.js? There are no docs on your website for using your product with nest.js and the example-app is very basic.
We have encountered this problem and I think it's not related to this plugin, but rather to AdminBro. Try changing component path from ./components/reference-in-list to path that goes back to main directory and then to component, for example: ../../../src/your/path/to/component/components/reference-in-list.
@SimonB407 Thanks for your help, but unfortunately it doesn't seem too work in my case :(
@humbkr which versions (admin-bro and plugins), do you use?
"dependencies": {
"@admin-bro/express": "^3.0.1",
"@admin-bro/mongoose": "^1.0.2",
"@admin-bro/nestjs": "^1.0.0",
"@nestjs/common": "^7.0.0",
"@nestjs/config": "^0.5.0",
"@nestjs/core": "^7.0.0",
"@nestjs/mongoose": "^7.0.2",
"@nestjs/platform-express": "^7.0.0",
"admin-bro": "^3.2.5",
"class-transformer": "^0.3.1",
"class-validator": "^0.12.2",
"express": "^4.17.1",
"express-formidable": "^1.2.0",
"express-session": "^1.17.1",
"mongoose": "^5.10.9",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.5.4"
},
Hi, I would like to also see some example using some async chain like this:
import { AdminModule } from '@admin-bro/nestjs';
import { Database, Resource } from '@admin-bro/typeorm';
import { GraphqlService, TypeOrmService } from '@config';
import * as Models from '@models';
import { User } from '@models';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ServeStaticModule } from '@nestjs/serve-static';
import { getRepositoryToken, TypeOrmModule } from '@nestjs/typeorm';
import AdminBro from 'admin-bro';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import * as Resolvers from './resolvers';
AdminBro.registerAdapter({ Database, Resource });
@Module({
imports: [
ServeStaticModule.forRoot({
renderPath: '/',
rootPath: join(__dirname, 'static'),
exclude: ['/graphql', '/admin'],
serveStaticOptions: {
redirect: true
}
}),
GraphQLModule.forRootAsync({
useClass: GraphqlService
}),
TypeOrmModule.forRootAsync({
useClass: TypeOrmService
}),
TypeOrmModule.forFeature([...Object.values(Models)]), // probably wrong
AdminModule.createAdminAsync({
imports: [TypeOrmModule.forFeature([...Object.values(Models)])],
inject: [getRepositoryToken(User)], // not working
useFactory: (adminModel: User) => ({
adminBroOptions: {
rootPath: '/admin',
resources: [{ resource: adminModel }]
}
})
})
],
controllers: [AppController],
providers: [...Object.values(Resolvers), AppService]
})
export class AppModule {}
If I am using async I am not able to use your package.
Thanks.
We have encountered this problem and I think it's not related to this plugin, but rather to AdminBro. Try changing component path from
./components/reference-in-listto path that goes back to main directory and then to component, for example:../../../src/your/path/to/component/components/reference-in-list.
Thanks @SimonB407 after spending an unbelievable amount of time trying to get a simple component to work this fixed the issue ...
component: AdminBro.bundle('./components/company-index')
to
component: AdminBro.bundle('../../src/admin-panel/components/company-index')
This is very unintuitive, especially when the first case "appears" to "build".
This is a great library, please find a way to include this in the documentation!
FYI: The error I got was
TypeError: Cannot read property 'createElement' of undefined

The origin was calling createElement on react_1.default which was undefiend.
My compiled js was:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const MyNewAction = (props) => {
return (react_1.default.createElement("div", null, "Test"));
};
exports.default = MyNewAction;
//# sourceMappingURL=company-index.js.map
My typescript was:
import React from 'react';
const MyNewAction = (props) => {
return (
<div>Test</div>
);
};
export default MyNewAction;
After a bit more investigation I figured out why this wasn't woking and how to get it to work.
What I originally failed to realise is that AdminBro.bundle expects the uncompiled component (in my case the .tsx file). I will say that again as it is not what I expected:
AdminBro.bundle expects the uncompiled component files
By using component: AdminBro.bundle('./components/company-index') it was finding the files in the dist folder where the tsx has been compiled by nestjs / tsc into js - this resulting js is not compatible with AdminBro.bundle. It is trying to use the version of react from the server not the browser!
By using component: AdminBro.bundle('../../../src/components/company-index') it was finding the files in the src folder where the uncompiled tsx file can be found and can be compiled and bundled byAdminBro.bundle. This is fine on my local dev environment .... but not so good on the server (where src does not exist).
To fix this I had to setup nestjs to copy the tsx component files to the dist folder without compiling them, that way AdminBro.bundle can compile them and bundle them up correctly for use in the browser.
Here are the steps I followed to achieve this:
Update nest-cli.json compilerOptions.assets to copy the tsx component files from my admin-panel/components folder in src:
"compilerOptions": {
"assets": [
"admin-panel/components/**"
]
}
Updated tsconfig to exclude src/admin-panel/components (you need do this in tsconfig.build.json tsconfig.json depending on your setup )
"exclude": [
"src/admin-panel/components",
]
You also don't need "jsx": "react", in the tsconfig compilerOptions if you are not compiling any tsx files with nestjs,
Finally I updated my AdminBro.bundle paths to be relative (without ../../src as suggested by @SimonB407 - which although it didn’t work I would never have figured this out without this hint so thanks again)
components: {
show: AdminBro.bundle('./components/resource-list-link'),
}
Hope this helps someone else.
I didn't manage to make NestJS's asset feature work. It simply didn't copy anything. So I ended up adding a script to create a symlink.
{
"link-admin-components-assets": "ln -s $PWD/apps/server/src/admin-module/components $PWD/dist/apps/server/components"
}
and then
// __dirname = /path/to/myProject/dist/apps/server
components: {
list: AdminBro.bundle(path.join(__dirname, './components/EnumArray')),
},
Hi, I have same problem but my project uses -express.js -javascript I'm not sure what to do. I really confused. Can you please help me, thank you!
Thanks to @maxpeterson , I resolved the issue I had with user components not being bundled in prod build.
If anyone else is struggling with bundling of custom components in production, you can use my commit here as a reference.
If you're struggling with nestjs+adminjs setup in general, I guess, you can use my repo for reference too. It's not very clean and there is only one entity hooked up, but it should clear some things up, if you're struggling.
Hi, I have same problem but my project uses -express.js -javascript I'm not sure what to do. I really confused. Can you please help me, thank you!
If you're using bare express.js (without any frameworks built on top if it), you should use https://github.com/SoftwareBrothers/adminjs-expressjs instead.
Thank you all of the above comments, I learned a lot from them (especially dklymenk's commit diff view) and here are some more steps I configured on my nestjs repo to get it work:
my nest-cli.json
"compilerOptions": {
"assets": [
{
"include": "admin/components/*.tsx",
"outDir": "dist/src"
}
]
}
I made this tweak to make sure the bundling matches the dir in dist
And I manually deleted .adminjs folder, otherwise sometimes it won't get overwritten and therefore the newly bundled component metadata is not added there, and causing some undefined errors when getting components.
Thanks to @maxpeterson this solved our problem in the latest version of Adminjs. This works as well with the new API
componentLoader.add('showImages', './components/images.show.tsx')