Hello,
I was trying to use Forest types in our project but have some troubles to use it
Expected behavior
Having no error when trying to used Forest types in our collections
Actual behavior
collection("CardSettings", {
fields: [
{
field: "id",
type: "String" as FieldType,
isSortable: true,
isFilterable: true,
},
...
],
});
And the second one :
collection("Account", {
fields: [
{
field: "holderType",
type: "Enum" as FieldType,
enums: [...identityTypeEnum],
},
{
field: "holderName",
type: "String" as FieldType,
isFilterable: true,
filter: ({ condition }) => filterOnHolderName(condition),
search: (query, search) => searchOnHolderName(query, search),
},
],
});
Failure Logs
'isSortable' does not exist in type 'SmartFieldOptions'
Type 'Promise<{ id: string[]; }>' is not assignable to type 'WhereOptions'
on filter
field
Context
- Package Version: 8.2.8
- Express Version: 4.17.1
- Sequelize Version: 5.22.3
- Database Dialect: postgresql
- Database Version:
- Project Name: Swan Back-Office
Thanks
Helo @Quentin_Giraud
Thanks for opening a thread in the community
Indeed, the isSortable
option is not available for smart fields, so no errors to me so far, please see the related section in the documentation.
Regarding the second issue related to your filter implementation, may I see the definition of the function filterOnHolderName(condition)
please ? Do note that the filter attribute on a smart field should contain a function returning an Sequelize Filter. In your case it looks like filterOnHolderName
returns a promise: Promise<{ id: string[]; }>
Awaiting your answer,
Steve.
Thanks for your answer
For the isSortable
, CardSettings
is a smart collection, the sort is doing in our graphql call to an other service, so it is necessary for us
About the holderName
field, here the function :
const filterOnHolderName = async (context: {
condition: { value: string; operator: ForestOperator };
}) => {
const parser = new FilterParser({ fields: [] }, "Europe/Paris");
const splittedName = context.condition.value.split(" ");
const firstName = splittedName[0];
const lastName = splittedName[1];
const [filterCompanyName, filterFirstName, filterLastName] = await Promise.all([
parser.formatCondition({
field: "name",
operator: context.condition.operator,
value: context.condition.value,
}),
parser.formatCondition({
field: "firstName",
operator: context.condition.operator,
value: firstName,
}),
parser.formatCondition({
field: "lastName",
operator: context.condition.operator,
value: lastName,
}),
]);
const where = {
[Op.or]: {
...filterCompanyName,
...filterFirstName,
...filterLastName,
},
};
const accounts = await AccountModel.findAll({
attributes: ["id"],
include: [
{
required: true,
attributes: [],
model: AccountHolder,
where,
},
],
});
return { id: accounts.map(account => account.id) };
};
It returns a Promise yes, but, actually, it does work like this on our back-office
If you have any alternatives on those 2 points I would be interested
An other issue on smart actions load hook :
As indicates here : Upgrade to v8 - Documentation I have the following code
hooks: {
load: async ({ fields, request }) => {
const [id] = await new RecordsGetter(model, request.user, request.query)
.getIdsFromRequest(request);
// or
const id = request.body.data.attributes.ids[0];
const record = await model.findByPk(id);
const field = fields.find(field => field.field === 'a field');
field.value = record.aProps;
return fields;
},
}
But the return type of SmartActionLoadHook
is SmartActionLoadHookField[]
, so I have one more issue because it does not accept Promise<SmartActionLoadHookField[]