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-list
to 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')