Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart action hook previousValue wrongly set #1010

Open
FrancisRoc opened this issue Sep 21, 2022 · 1 comment
Open

Smart action hook previousValue wrongly set #1010

FrancisRoc opened this issue Sep 21, 2022 · 1 comment

Comments

@FrancisRoc
Copy link

FrancisRoc commented Sep 21, 2022

Expected behavior

changedField.previousValue should be properly set on the 'Number of values' field whatever the position of that field is (See context it will be more clear)

Actual behavior

If my 'Number of values' number input field is not at the 4th position (index = 3) the hook previous value is always null and it seems that whatever the field that is at the 4th position in the array has it's previous value set instead of my number input

Failure Logs

None

Context

Please help this makes no sense to me. Also note that all fields before the prblematic one is not added or removed dynamically so that can't really change the position on 'Number of values' field

Smart action:

export enum EnterpriseCollectionFields {
  Name = 'Name',
  OfferCard = 'Offer mobility card',
  Type = 'Spending rules type',
  ShortDescription = 'Short Description (Summary)',
  Description = 'Description',
  Value = 'Value',
  DailyLimit = 'Daily limit',
  TransactionLimit = 'Transaction limit',
  MonthlyAllocation = 'Monthly allocation'
}

export declare enum SpendingRuleType {
    StripeMerchant = "stripeMerchant",
    StripeCategory = "stripeCategory",
    CommutifiPlan = "commutifiPlan",
    Wallet = "wallet"
}

{
      name: 'Create Wallet',
      type: 'single',
      fields: [
        {
          field: EnterpriseCollectionFields.OfferCard,
          description:
            'Weather this wallet will setup a Commutifi card or not. Then rules like Stripe categories can be applied',
          type: 'Boolean',
          hook: 'onOfferCardChanged',
          isRequired: true,
          defaultValue: false
        },
        {
          field: EnterpriseCollectionFields.Type,
          description: 'Type of spending rule restrictions you want to add',
          type: 'Enum',
          enums: Object.values(SpendingRuleType),
          hook: 'onTypeChanged',
          isRequired: true
        },
        {
          field: 'Number of values',
          description: 'How many plans or stripe categories you want to add ?',
          type: 'Number',
          defaultValue: 1,
          hook: 'onNbValueChange'
        },
        {
          field: EnterpriseCollectionFields.Value,
          description:
            'Commutifi Plan ids, Stripe categories or leave empty if you are making a global rule for the wallet (Ex. monthly limit only or days limit)',
          type: 'String',
          reference: 'plans.id'
        },
        {
          field: EnterpriseCollectionFields.Name,
          description: 'Wallet Name that employee will see',
          type: 'String',
          isRequired: true
        },
        {
          field: EnterpriseCollectionFields.Description,
          description:
            'Long Wallet description. Markdown available in wallet detail view but we can only use a simple text here ...',
          type: 'String',
          isRequired: true
        },
        {
          field: EnterpriseCollectionFields.ShortDescription,
          description: 'Quick 50 max characters description of the wallet',
          type: 'String',
          isRequired: true,
          hook: 'onDescriptionChange'
        },

        {
          field: EnterpriseCollectionFields.DailyLimit,
          description: 'Daily max amount spent (in cents)',
          type: 'Number'
        },
        {
          field: EnterpriseCollectionFields.TransactionLimit,
          description: 'Max amount PER transaction (in cents)',
          type: 'Number'
        }
      ],
      hooks: {
        change: {
          onOfferCardChanged: ({ fields, changedField }) => {
            if (changedField.value === true) {
              fields.push({
                previousValue: undefined,
                value: undefined,
                field: EnterpriseCollectionFields.MonthlyAllocation,
                type: 'Number',
                isRequired: true
              })
            } else {
              const index = fields.findIndex(
                (f) => f.field === EnterpriseCollectionFields.MonthlyAllocation
              )
              fields.splice(index, 1)
            }
            return fields
          },
          onTypeChanged: ({ fields, changedField }) => {
            const fieldsIndexToMutate = []
            fields.forEach((field, i) =>
              field.field.startsWith(EnterpriseCollectionFields.Value)
                ? fieldsIndexToMutate.push(i)
                : null
            )

            switch (changedField.value) {
              case SpendingRuleType.CommutifiPlan:
                fieldsIndexToMutate.forEach((index) => {
                  const field = fields[index]
                  field.isRequired = true
                  field.type = 'String'
                  field.reference = 'plans.id'
                  field.enums = null
                  // @ts-ignore
                  field.widgetEdit = {
                    name: 'belongsto typeahead',
                    parameters: {}
                  }
                })
                break
              case SpendingRuleType.StripeMerchant:
                fieldsIndexToMutate.forEach((index) => {
                  const field = fields[index]
                  field.isRequired = true
                  field.type = 'String'
                  field.reference = null
                  field.enums = null
                  // @ts-ignore
                  field.widgetEdit = {
                    name: 'text editor',
                    parameters: {}
                  }
                })
                break
              case SpendingRuleType.Wallet:
                fieldsIndexToMutate.forEach((index) => {
                  const field = fields[index]
                  field.isRequired = false
                  field.type = 'String'
                  field.reference = null
                  field.enums = null
                  // @ts-ignore
                  field.widgetEdit = {
                    name: 'text editor',
                    parameters: {}
                  }
                })
                break

              default:
                break
            }
            return fields
          },
          onNbValueChange: ({ changedField, fields }) => {
            if (changedField.value < 0) {
              return fields
            }
            const previousValue = changedField.previousValue ?? 1
            const value = changedField.value ?? 1
            const valueFieldIndex = fields.findIndex((field) =>
              field.field.startsWith(EnterpriseCollectionFields.Value)
            )
            const index =
              valueFieldIndex >= 0
                ? valueFieldIndex
                : fields.findIndex(
                    (field) => field.field === 'Number of values'
                  ) + 1
            if (previousValue < value) {
              const newFieldAmount = value - previousValue
              fields.splice(
                index + previousValue,
                0,
                // times function is from lodash
                ...times(newFieldAmount, (i) => ({
                  previousValue: undefined,
                  value: undefined,
                  ...walletPlanValueField,
                  field: `${EnterpriseCollectionFields.Value}${
                    previousValue + i
                  }`
                }))
              )
            } else if (previousValue > value) {
              const deleteFieldAmount = previousValue - value
              fields.splice(index + value, deleteFieldAmount)
            }

            return fields
          },
          onDescriptionChange: ({ fields, changedField }) => {
            if (
              typeof changedField.value === 'string' &&
              changedField.value.length > 50
            ) {
              changedField.value.substring(0, 50)
            }
            return fields
          }
        }
      }
    }

In that configuration ⬆️ I can't get the number input to work with adding value fields properly because the previous value is set on the wrong item in the fields array
image

But the position in the schema is right
image

Screen record of bad behavior (Number of values is 3rd in array -> index 2)

bad-previous-value

Screen record of good behavior (Number of values is 4th in array -> index 3)

good-previous-value

  • Package Version: "forest-express-sequelize": "~8.5.10",
  • Express Version: "express": "~4.17.1"
  • Sequelize Version: "sequelize": "~5.15.1",
  • Database Dialect: Postgres
  • Database Version: "pg": "~8.2.2",
@FrancisRoc
Copy link
Author

FrancisRoc commented Sep 21, 2022

I have similar issues now but at one index further in the array. It's like if the schema wasn't updated and something triggers a change and then if I don't use the number input at a specific index the previousValue isn't set on the proper field but I check and it is and the browser displays the message notifying of an update and I do a refresh. Also tried incognito and same issue :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant