Feature(s) impacted
in order to change a gender for EXAMPLE i want to show a dropdown list instead of text input.
I would like to do this on code not on the UI.
Context
migration from forest v9 to the new nodejs agent.
in the old forest version I was editing in the models files but in the new forest agent I dont find a way to do the same.
Project name: Clevermate v2
Agent technology: (nodejs,
Agent (forest package) name & version: …
Database type: postges
Hello @Adel_de_Clevermate ,
The agent should pick up what is defined in your ORM models or database and use that in the schema.
Do you have an enum in either of those ?
Thanks
Hi @Nicolas.M
No, I dont have. the field on databse is of type varchar, I dont get where I can see the ORM models.
Ok,
What you can do is use an addField
customization on the collection. Something like that should work for you:
UserCollection.addField('UserGenderWithEnum', {
columnType: 'Enum',
enumValues: ['M', 'F', 'O'],
dependencies: ['UserGender'],
getValues(records) {
return records.map(record => {
switch (record.UserGender) {
case 'M':
case 'Male':
return 'M';
case 'F':
case 'Female':
return 'F';
case 'O':
case 'Other':
return 'O';
default:
return null;
}
});
},
})
.removeField('UserGender')
.replaceFieldWriting('UserGenderWithEnum', async value => {
return { UserGender: value };
});
Please note that you may have to enable writing for the field in the UI, as computed fields are readonly by default.
It will effectively replace the UserGender
field with UserGenderWithEnum
in your forest schema
Please let me know if this is ok for your use case
Thank you @Nicolas.M
This looks good to resolve the issue.
Unless there is other simpler way with less code lines, since we have many more fields like this and on many collections.
Thank you
You may want to look into factorizing your enum declarations using plugins.
Here is very similar example in our plugins repo:
The plugin allows you to create fields based on enums when your database stores technical values (0, 1, 2, 3).
```typescript
import { createAgent } from '@forestadmin/agent';
import { Schema } from './typings';
import defineEnum from '@forestadmin-experimental/plugin-define-enum';
import type { DefineEnumOption } from '@forestadmin-experimental/plugin-define-enum';
const BandStatus = {
JustCreated: 0,
GrowingHigh: 50,
BrokenUp: 100,
} as const
await createAgent<Schema>(Options)
.addDataSource(DataSourceOptions)
.customizeCollection('users', usersCollection => {
.use<DefineEnumOption<Schema, 'users'>>(defineEnum, {
This file has been truncated. show original
import type { Plugin, TCollectionName, TSchema } from '@forestadmin/datasource-customizer';
import { Options } from './types';
export { Options as DefineEnumOption };
export default function defineEnum<
S extends TSchema = TSchema,
N extends TCollectionName<S> = TCollectionName<S>,
>(dataSource, collection, options?: Options<S, N>) {
if (!collection) throw new Error('defineEnum may only be use() on a collection.');
if (!options) throw new Error('Options must be provided.');
const { fieldName, enumFieldName, enumObject } = options;
const newFieldName = enumFieldName ?? `${fieldName}Enum`;
collection
.addField(newFieldName, {
columnType: 'Enum',
enumValues: Object.keys(enumObject),
This file has been truncated. show original
You can take inspiration from there to limit boilerplate in your customization code.
I hope this helps
1 Like