Typescript: types errors

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 :wave:

Thanks for opening a thread in the community :raised_hands:

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 :pray:t2:

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[]