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

fix(frontend): It is ambiguous on what scale is the withdrawal and deposit input #2817

Merged
merged 8 commits into from
Jul 31, 2024

Conversation

Emanuel-Palestino
Copy link
Contributor

@Emanuel-Palestino Emanuel-Palestino commented Jul 18, 2024

Changes proposed in this pull request

  • Add an asset prop in liquidity dialog component to receive the asset info.
  • Get the asset info on the loader of withdraw and deposit components using the getPeer api method.
  • Get the asset info on the loader of withdraw and deposit components using the getAssetInfo api method.

Context

In the rafiki Admin UI, the liquidity information of peer and asset details are displayed using the current asset scale. When the user wants to deposit or withdraw liquidity, the amount introduced is handle using a scale of 0. So it is ambiguous on what scale the user is withdrawing or depositing.

Fixes: #2798

@github-actions github-actions bot added the pkg: frontend Changes in the frontend package. label Jul 18, 2024
Copy link

netlify bot commented Jul 18, 2024

Deploy Preview for brilliant-pasca-3e80ec ready!

Name Link
🔨 Latest commit 4232609
🔍 Latest deploy log https://app.netlify.com/sites/brilliant-pasca-3e80ec/deploys/66a913e487382a0008c71c42
😎 Deploy Preview https://deploy-preview-2817--brilliant-pasca-3e80ec.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@BlairCurrey BlairCurrey changed the title Fix: It is ambiguous on what scale is the withdrawal and deposit input fix(frontend): It is ambiguous on what scale is the withdrawal and deposit input Jul 22, 2024
Comment on lines 61 to 62
<p>Based on the asset:</p>
<p>Amount {amount} = {amount / Math.pow(10, asset.scale)} {asset.code} </p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be simplified a bit. I don't think we need to restate the amount since its in the input nor that it's translating to the current asset scale because of the context.

I think this would be fine:

Suggested change
<p>Based on the asset:</p>
<p>Amount {amount} = {amount / Math.pow(10, asset.scale)} {asset.code} </p>
<p>
{amount / Math.pow(10, asset.scale)} {asset.code}{' '}
</p>

image

But perhaps a dummy input field for the asset scale really drives home the point (user can see 0 and 100 => 100, 2 and 100 => 1, etc.):

                  <Input
                    required
                    disabled
                    type='number'
                    label='Asset Scale'
                    value={asset.scale}
                  />

image

Copy link
Contributor

@BlairCurrey BlairCurrey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Emanuel-Palestino thank you for the contribution - this looks great. Functionality is good, just left a couple style suggestions.

@JoblersTune
Copy link
Collaborator

Thanks Blair. Iwiill add my review on Wednesday as well. Just OOO right now.

Added styles for fields consistent

Co-authored-by: Blair Currey <12960453+BlairCurrey@users.noreply.github.com>
@Emanuel-Palestino
Copy link
Contributor Author

Hello @BlairCurrey , I was thinking about your suggestions using a simplified description and the possibility of adding a dummy input. I think the best option is to use a simplified description, I coded it.

I also thought in another approach:

  • I can use the addOn input prop to display the asset code in the input, so that with this change, the user can clearly know the unit of their deposit or withdrawal. Then, when the user submits the form, the amount can be captured and converted from original asset scale to 0 (which is the scale the backend expects to receive).
    • Screenshot
      image

I would like to know your feedback too @JoblersTune c:

@JoblersTune
Copy link
Collaborator

@Emanuel-Palestino that's a great suggestion to use the addOn input prop. I think you're onto something. Then we can abstract all the complexity foir the users entirely. What about something like this?

export const LiquidityDialog = ({
  title,
  onClose,
  type,
  asset
}: LiquidityDialogProps) => {
  const [actualAmount, setActualAmount] = useState<number>(0)
  const [errorMessage, setErrorMessage] = useState<string>('')

  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const userInput = e.target.value
    const scaledInput = Number(userInput) * Math.pow(10, asset.scale)
    const integerScaledInput = Math.floor(scaledInput)
    if (scaledInput !== integerScaledInput) {
      const error = 'The asset scale cannot accomodate this value'
      setErrorMessage(error)
    } else {
      setErrorMessage('')
    }
    setActualAmount(integerScaledInput)
  }

  return (
    <Dialog as='div' className='relative z-10' onClose={onClose} open={true}>
      <div className='fixed inset-0 bg-tealish/30 bg-opacity-75 transition-opacity' />
      <div className='fixed inset-0 z-10 overflow-y-auto'>
        <div className='flex min-h-full items-center justify-center p-4 text-center'>
          <Dialog.Panel className='relative transform overflow-hidden rounded-lg max-w-full transition-all bg-white px-4 pb-4 pt-5 text-left shadow-xl w-full sm:max-w-lg'>
            <div className='absolute right-0 top-0 pr-4 pt-4'>
              <button
                type='button'
                className='text-gray-400 hover:text-gray-500 focus:outline-none'
                onClick={onClose}
              >
                <span className='sr-only'>Close</span>
                <XIcon className='h-8 w-8' aria-hidden='true' />
              </button>
            </div>
            <div>
              <Dialog.Title
                as='h3'
                className='font-semibold leading-6 text-lg text-center'
              >
                {title}
              </Dialog.Title>
              <div className='mt-2'>
                <Input
                  required
                  type='number'
                  name='displayAmount'
                  label='Amount'
                  onChange={handleChange}
                  addOn={asset.code}
                  step='any'
                  error={errorMessage}
                />
                <Form method='post' replace preventScrollReset>
                  <Input
                    required
                    min={1}
                    type='hidden'
                    name='amount'
                    value={actualAmount}
                  />
                  <div className='flex justify-end py-3'>
                    <Button aria-label={`${type} liquidity`} type='submit'>
                      {type} liquidity
                    </Button>
                  </div>
                </Form>
              </div>
            </div>
          </Dialog.Panel>
        </div>
      </div>
    </Dialog>
  )
}

This way with the visible input we can display the value in asset scale 0, the same way we display the liquidity info, but with the hidden field we can submit the value in the relevant asset scale.

What do you think?


return (
<LiquidityDialog
onClose={dismissDialog}
title='Deposit asset liquidity'
type='Deposit'
asset={asset}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
asset={asset}
asset={{ code: asset.code, scale: asset.scale }}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understand why you suggested this change, can you explain me please? 🙏

Copy link
Collaborator

@JoblersTune JoblersTune Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Since the definition for the BasicAsset is only scale and code this makes it more clear what we are passing in (not the entire asset is used, only code and scale). In other words it has better type matching.

type BasicAsset = {
  code: string
  scale: number
}

type LiquidityDialogProps = {
  title: string
  onClose: () => void
  type: 'Deposit' | 'Withdraw'
  asset: BasicAsset
}

So having

return (
    <LiquidityDialog
      onClose={dismissDialog}
      title='Deposit asset liquidity'
      type='Deposit'
      asset={{ code: asset.code, scale: asset.scale }}
    />
)

Explicitly matches what we have set in the props definition

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, it makes sense thank you


return (
<LiquidityDialog
onClose={dismissDialog}
title='Withdraw asset liquidity'
type='Withdraw'
asset={asset}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
asset={asset}
asset={{ code: asset.code, scale: asset.scale }}


return (
<LiquidityDialog
onClose={dismissDialog}
title='Deposit peer liquidity'
type='Deposit'
asset={asset}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
asset={asset}
asset={{ code: asset.code, scale: asset.scale }}


return (
<LiquidityDialog
onClose={dismissDialog}
title='Withdraw peer liquidity'
type='Withdraw'
asset={asset}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
asset={asset}
asset={{ code: asset.code, scale: asset.scale }}

@BlairCurrey
Copy link
Contributor

Hello @BlairCurrey , I was thinking about your suggestions using a simplified description and the possibility of adding a dummy input. I think the best option is to use a simplified description, I coded it.

I also thought in another approach:

  • I can use the addOn input prop to display the asset code in the input, so that with this change, the user can clearly know the unit of their deposit or withdrawal. Then, when the user submits the form, the amount can be captured and converted from original asset scale to 0 (which is the scale the backend expects to receive).

    • Screenshot
      image

I would like to know your feedback too @JoblersTune c:

addOn looks great 👍. And converting to 0 on submit as you and Sarah are suggesting looks like a good solution.

@Emanuel-Palestino
Copy link
Contributor Author

@JoblersTune that's a great implementation. I will work on it.

@Emanuel-Palestino
Copy link
Contributor Author

I have made the implementation. Waiting for your feedback c:

Additionally, working in the project I found and issue and a suggestion to improve de UX related to assets and peers pages.

  • In the asset details page, when a modal is opened, the scroll is setted to the top. This doesn't happen in peers details page.
  • I think it's a good idea to make de user input auto focusable, so that the user can type at the same time it opened the modal.

I don't know if I can make this changes in this pull request, or I have to open a new issue.

@BlairCurrey
Copy link
Contributor

I have made the implementation. Waiting for your feedback c:

Additionally, working in the project I found and issue and a suggestion to improve de UX related to assets and peers pages.

  • In the asset details page, when a modal is opened, the scroll is setted to the top. This doesn't happen in peers details page.
  • I think it's a good idea to make de user input auto focusable, so that the user can type at the same time it opened the modal.

I don't know if I can make this changes in this pull request, or I have to open a new issue.

Looks good to me @Emanuel-Palestino. Just a small fix to make prettier happy. #2817 (comment)

The UX suggestions are good. Lets address that in another issue. Made one here: #2825 Feel free to assign yourself if you'd like.

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I move the input out of the form, but I notice when the user submits the form it doesn't make the native html validation and it doesn't prevent the user from submitting any amount. The validation is made succesfully until the amount reaches the backend.
I understand that what you mention is also important. What do you think? @JoblersTune

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I was hoping the error message would cover that, even more so with your added minimum specification. Can you give me an example of where it is still failing @Emanuel-Palestino?

Copy link
Contributor Author

@Emanuel-Palestino Emanuel-Palestino Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. When I submit a negative value or a very small value, it submits to the backend.

  • Negative values, the error message doesn't appear and the validation is made in the backend.
    image

  • With very small value, the error message appear (although it doesn't prevent to the user from submit). The validation is made in the backend.
    image

The message displayed at the top, is made by the backend. @JoblersTune these are the examples where it fail.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Emanuel-Palestino good catch on the negative values, thanks. We do most of our validation on the backend already. It creates a simpler frontend with faster load times and less JS complexity. We want to validate our input on the backend since that is where we'll be using it, so while it's nice to have frontend, reactive and immediate feedback it can lead to slower load times and some redundancy since backend validation is required as well.

So it's fine to get a server-side error for incorrect data entries. However, let's mitigate this by just adding a frontend message for the case where the value is negative as well, to give users a clearer error where we can.

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const userInput = e.target.value
    const scaledInput = parseFloat(userInput) * Math.pow(10, asset.scale)
    const integerScaledInput = Math.floor(scaledInput)
    if (scaledInput < 0) {
      const error = 'The amount should be a positive value'
      setErrorMessage(error)
    } else if (scaledInput !== integerScaledInput) {
      const error = 'The asset scale cannot accomodate this value'
      setErrorMessage(error)
    } else {
      setErrorMessage('')
    }
    setActualAmount(integerScaledInput)
  }

And then keep that input value above the form element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, I'll make the changes c:

Copy link
Collaborator

@JoblersTune JoblersTune left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for your positive and engaged contribution!

@JoblersTune JoblersTune merged commit 9b7fcdc into interledger:main Jul 31, 2024
36 of 42 checks passed
sabineschaller pushed a commit that referenced this pull request Aug 15, 2024
…posit input (#2817)

* fix(frontend): asset scale consistency in liquidity dialogs.

* Ensure asset scale consistency when displaying and withdrawing liquidity by adding asset info to the liquidity dialog component and updating the input handling in Rafiki Admin UI.
---------

Co-authored-by: Blair Currey <12960453+BlairCurrey@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: frontend Changes in the frontend package.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Admin UI displays liquidity in one asset scale and withdrawal input in a different scale
3 participants