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:
parent
a2e85bb3eb
commit
2958a03c2c
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -425,6 +425,7 @@ StatusDropdown {
|
|||
name: chainName,
|
||||
icon: chainIcon,
|
||||
amount: asset.remainingSupply,
|
||||
decimals: asset.decimals,
|
||||
multiplierIndex: asset.multiplierIndex,
|
||||
infiniteAmount: asset.infiniteSupply
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue