Jsonforms integration in adminjs

hello,
is there a reason why my server can’t bundle correctly this code ?
can’t I use jsonforms as react component ?? it’s to make a customized component in adminjs
Thanks

import { allowOverride, Edit, EditPropertyProps, ShowPropertyProps} from ‘adminjs’;
import { FormGroup, FormMessage, Label, RichTextEditor, TextArea, Input } from ‘@adminjs/design-system’;
import React, { FC, useMemo, useState, ReactElement } from ‘react’;
import { JsonForms } from ‘@jsonforms/react’;
import { materialCells, materialRenderers} from ‘@jsonforms/material-renderers’;
const MyInputComponent:FC = (props): ReactElement => {
const schema = {
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”,
“minLength”: 1
},
“description”: {
“title”: “Long Description”,
“type”: “string”
}
},
“required”: [“name”]
}
const uischema={
“type”: “VerticalLayout”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/name”
},
{
“type”: “Control”,
“scope”: “#/properties/description”,
“options”: {
“multi”: true
}
}
]
}

const initialData = {}
const { property, record, onChange } = props

const [data, setData] = useState(initialData);
return (


<JsonForms
schema={schema}
uischema={uischema}
data={data}
renderers={materialRenderers}
cells={materialCells}
onChange={({ data }) => setData(data)}
/>
yyyyy

);
}
export default MyInputComponent

(my code is correctly working when i comment call in return)

Hi @clysss,

Can you explain what the issue is? On a first glance I would expect this to work.


Note that it seems that you are creating a new schema with every re-render of your MyInputComponent which will have a large performance penalty on JSON Forms. I would like to recommend placing the schema into a useMemo or moving it out of the render path.

i’ll try :slight_smile: to explain…
i’ve open also a question to adminjs on :

adminjs don’t bundle file but I don’t really know why… !
what is sure is that when I add jsonform into myinputcomponent, the time to load the server is so long…
How could I “move out of the render path” the schema? you mean put the const out of MyInputComponent ?
I changed the code to :
export default memo(MyInputComponent)
=> it’s worse, this seems to overload the server and never completly start
but perhaps you were talking about using useMemo during onchange ?

thx sdirix

I’m not familiar with adminjs. Looking at the docs it seems like you explicitly need to declare which components you are using, see here. So I would expect that you also need to add the MyInputComponent somewhere.

when I remove the call to jsonforms (ie when I put // in front of) the component is correctly called and I see the DIV…

Hi @clysss , did you try moving your schema definition either completely outside the component or use React’s useMemo hook to avoid recreating it everytime?
I could imagine there being some endless re-rendering loop with the schema being re-created on every re-render like in your code snippet above.

Interesting
Where should I put the usememo in your opinion?
For adminjs it could be come from mui renderers as adminjs don’t use them
Could this help you?

Hi @clysss,
Please have a look at the useMemo documentation here: useMemo – React

For your schema this could look like this:

const schema = React.useMemo(() => ({
  “type”: “object”,
  “properties”: {
  “name”: {
  “type”: “string”,
  “minLength”: 1
  },
  “description”: {
  “title”: “Long Description”,
  “type”: “string”
  }
  },
  “required”: [“name”]
}), []);

Note that you also need to do this for the uischema.

I add use.Memo but it’s worse !
to resume :slight_smile:

  • when I use not useMemo and only MUI button , the component is correctly bundled
  • when I use use Memo and only < Button> => error

import { allowOverride, Edit, BasePropertyProps } from ‘adminjs’;
import { FormGroup, FormMessage, Label, RichTextEditor, TextArea, Input } from ‘@adminjs/design-system’;
import React, { FC, useMemo, useState, ReactElement } from ‘react’;
import { JsonForms } from ‘@jsonforms/react’;
import { Grid, Button, Typography } from ‘@mui/material’;
import { materialCells, materialRenderers } from ‘@jsonforms/material-renderers’;
const schema = React.useMemo(() => ({
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”,
“minLength”: 1
},
“description”: {
“title”: “Long Description”,
“type”: “string”
}
},
“required”: [“name”]
}), );

const uischema = React.useMemo(() => ({
“type”: “VerticalLayout”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/name”
},
{
“type”: “Control”,
“scope”: “#/properties/description”,
“options”: {
“multi”: true
}
}
]
}), );

const initialData = {}

//const MyInputComponent:FC = (props): ReactElement => {
const MyInputComponent = (props: BasePropertyProps) => {

const { property, record, onChange } = props

const [data, setData] = useState(initialData);
return (
/*

  <JsonForms
    schema={schema}
    uischema={uischema}
    data={data}
    renderers={materialRenderers}
    cells={materialCells}
    onChange={({ data }) => setData(data)}
  />
  aaaa

  bbbbb

*/

  <Button>xxxx</Button>
  //</div>

);
}

export default MyInputComponent

Hi @clysss,

You need to do one of the following, not both:

  • Use useMemo but do it within the MyInputComponent. useMemo is a hook and can only be used within “render” code
  • Keep the schema and uischema outside of MyInputComponent, but then remove the useMemo

ok undestood
but not better :
i also use to add memory cf : [Bug]: can't correctly create custom component when importing external lib · Issue #1674 · SoftwareBrothers/adminjs · GitHub
but without success

after upgrading server to 16Go mem and 12Go stack, , has been able to bundle and see the component. :slight_smile:
but it takes 18 minutes to start and of course I can’t afford a 16Go server for that!!
So… how can I “import files from their librarie so that tree shaking works” ?
thx

– ok –
not found a solution after a week. I forget adminjs and use another crud solution