fix(airdrop): fix decimals validation

* set decimal for assets on AidropSettingsPanel and HoldingsDropdown test pages
* Disable amount length validation by default
* Input: Align validation error string to the left edge
* Update validation error copy

fixes #11918
This commit is contained in:
Andrey Bocharnikov 2024-03-05 18:12:03 +04:00
parent a2e85bb3eb
commit 2958a03c2c
8 changed files with 80 additions and 27 deletions

View File

@ -177,6 +177,10 @@ SplitView {
name: "chainName"
expression: model.index ? "Ethereum Mainnet" : "Goerli"
},
ExpressionRole {
name: "decimals"
expression: decimalsText.text
},
ExpressionRole {
readonly property string icon1: "network/Network=Ethereum"
@ -192,7 +196,6 @@ SplitView {
value: TokenCategories.Category.Community
}
Component.onCompleted: {
Qt.callLater(() => airdropsSettingsPanel.assetsModel = this)
}
@ -250,6 +253,19 @@ SplitView {
text: "Owner and TMaster tokens deployed"
}
Row {
Label {
anchors.verticalCenter: parent.verticalCenter
text: "Assets Decimals"
}
TextField {
id: decimalsText
text: "2"
width: 50
}
}
}
}
}

View File

@ -119,7 +119,10 @@ SplitView {
expression: model.index ? "Ethereum Mainnet" : "Goerli"
},
ExpressionRole {
name: "decimals"
expression: decimalsText.text
},
ExpressionRole {
readonly property string icon1: "network/Network=Ethereum"
readonly property string icon2: "network/Network=Testnet"
@ -169,6 +172,16 @@ SplitView {
id: ctrlAllTokensMode
text: "All tokens mode"
}
Label {
text: "Assets Decimals"
}
TextField {
id: decimalsText
Layout.preferredWidth: 50
text: "2"
}
}
}
}

View File

@ -24,28 +24,32 @@ SplitView {
icon: Style.svg(ModelsData.networks.optimism),
amount: "300",
multiplierIndex: 0,
infiniteAmount: false
infiniteAmount: false,
decimals: 6
},
{
name: "Arbitrum",
icon: Style.svg(ModelsData.networks.arbitrum),
amount: "400000",
multiplierIndex: 3,
infiniteAmount: false
infiniteAmount: false,
decimals: 9
},
{
name: "Hermez",
icon: Style.svg(ModelsData.networks.hermez),
amount: "0",
multiplierIndex: 0,
infiniteAmount: true
infiniteAmount: true,
decimals: 0
},
{
name: "Ethereum",
icon: Style.svg(ModelsData.networks.ethereum),
amount: "12" + "0".repeat(18),
multiplierIndex: 18,
infiniteAmount: false
infiniteAmount: false,
decimals: 9
}
]
@ -130,10 +134,24 @@ SplitView {
text: "∞"
}
Label {
text: "Decimals:"
}
TextField {
id: decimalsTextField
text: "0"
}
}
Label {
text: "amount: " + tokenPanel.amount
RowLayout {
Label {
text: "amount: " + tokenPanel.amount
}
Label {
text: "decimals: " + tokenPanel.decimals
}
}
}
}

View File

@ -15,6 +15,7 @@ StatusComboBox {
readonly property string currentName: control.currentText
readonly property alias currentAmount: instantiator.amount
readonly property alias decimals: instantiator.decimals
readonly property alias currentMultiplierIndex: instantiator.multiplierIndex
readonly property alias currentInfiniteAmount: instantiator.infiniteAmount
readonly property alias currentIcon: instantiator.icon
@ -100,6 +101,7 @@ StatusComboBox {
property string amount
property int multiplierIndex
property bool infiniteAmount
property int decimals
model: SortFilterProxyModel {
sourceModel: root.model
@ -113,6 +115,7 @@ StatusComboBox {
readonly property list<Binding> bindings: [
Bind { property: "icon"; value: model.icon },
Bind { property: "amount"; value: model.amount },
Bind { property: "decimals"; value: model.decimals },
Bind { property: "multiplierIndex"; value: model.multiplierIndex },
Bind { property: "infiniteAmount"; value: model.infiniteAmount }
]

View File

@ -21,6 +21,7 @@ ColumnLayout {
property alias tokenImage: item.iconSource
property alias amountText: amountInput.text
property alias amount: amountInput.amount
property alias decimals: amountInput.tokenDecimals
property alias multiplierIndex: amountInput.multiplierIndex
property alias tokenCategoryText: tokenLabel.text
property alias networkLabelText: d.networkLabelText
@ -88,6 +89,7 @@ ColumnLayout {
spacing: 10
property alias currentAmount: inlineNetworksComboBox.currentAmount
property alias decimals: inlineNetworksComboBox.decimals
property alias currentMultiplierIndex:
inlineNetworksComboBox.currentMultiplierIndex
property alias currentInfiniteAmount:
@ -128,7 +130,8 @@ ColumnLayout {
maximumAmount: !!networksComboBoxLoader.item
? networksComboBoxLoader.item.currentAmount : "0"
tokenDecimals: !!networksComboBoxLoader.item
? networksComboBoxLoader.item.decimals : 0
multiplierIndex: !!networksComboBoxLoader.item
? networksComboBoxLoader.item.currentMultiplierIndex : 0

View File

@ -425,6 +425,7 @@ StatusDropdown {
name: chainName,
icon: chainIcon,
amount: asset.remainingSupply,
decimals: asset.decimals,
multiplierIndex: asset.multiplierIndex,
infiniteAmount: asset.infiniteSupply
})

View File

@ -10,7 +10,6 @@ import utils 1.0
Input {
id: root
property int maximumLength: 10
property var locale: LocaleUtils.userInputLocale
readonly property alias amount: d.amount
@ -18,6 +17,7 @@ Input {
readonly property bool valid: validationError.length === 0
property bool allowDecimals: true
property int tokenDecimals: 0
property bool validateMaximumAmount: false
property string maximumAmount: "0"
@ -66,17 +66,12 @@ Input {
if (!root.allowDecimals)
root.text = root.text.replace(root.locale.decimalPoint, "")
if(root.text.length === 0) {
if (root.text.length === 0) {
d.amount = "0"
root.validationError = ""
return
}
if (d.getEffectiveDigitsCount(text) > root.maximumLength) {
root.validationError = qsTr("The maximum number of characters is %1").arg(root.maximumLength)
return
}
const amountNumber = LocaleUtils.numberFromLocaleString(root.text, root.locale)
if (isNaN(amountNumber)) {
d.amount = "0"
@ -84,23 +79,26 @@ Input {
return
}
const fractionalPartLength = LocaleUtils.fractionalPartLength(amountNumber)
if (fractionalPartLength > root.tokenDecimals) {
d.amount = "0"
root.validationError = qsTr("Max %n decimal place(s) for this asset", "", root.tokenDecimals)
return
}
if (!root.allowZero && amountNumber === 0) {
d.amount = "0"
root.validationError = qsTr("Amount must be greater than 0")
return
}
const amount = SQUtils.AmountsArithmetic.fromNumber(
amountNumber, d.multiplierIndex)
const amount = SQUtils.AmountsArithmetic.fromNumber(amountNumber, d.multiplierIndex)
if (root.validateMaximumAmount) {
const maximumAmount = SQUtils.AmountsArithmetic.fromString(
root.maximumAmount)
if (root.validateMaximumAmount && root.maximumAmount && root.maximumAmount.length > 0) {
const maximumAmount = SQUtils.AmountsArithmetic.fromString(root.maximumAmount)
const maxExceeded = SQUtils.AmountsArithmetic.cmp(amount, maximumAmount) === 1
const maxExceeded = SQUtils.AmountsArithmetic.cmp(
amount, maximumAmount) === 1
if (SQUtils.AmountsArithmetic.cmp(amount, maximumAmount) === 1) {
if (maxExceeded) {
root.validationError = root.maximumExceededErrorText
return
}
@ -110,7 +108,7 @@ Input {
// As a target amount should be always integer number
if (!Number.isInteger(amountNumber) && d.multiplierIndex === 0) {
d.amount = amount.toString()
} else {
} else {
d.amount = amount.toFixed(0)
}

View File

@ -177,9 +177,10 @@ Item {
id: validationErrorText
visible: !!validationError
text: validationError
anchors.left: inputField.left
anchors.leftMargin: 2
anchors.top: inputField.bottom
anchors.topMargin: validationErrorTopMargin
width: parent.width
horizontalAlignment: Text.AlignRight
font.pixelSize: 12
height: 16