From 739a3f34a7bf9d3533dedb6c74bc532806665e24 Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Sat, 18 Jul 2026 09:06:34 -0300 Subject: [PATCH] fix(liquidity): mark missing holding input --- .../components/liquidity/NewPositionForm.qml | 28 +++++++++++++------ apps/amm/tests/qml/tst_NewPositionForm.qml | 15 ++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/amm/qml/components/liquidity/NewPositionForm.qml b/apps/amm/qml/components/liquidity/NewPositionForm.qml index 1769325..a33f3e0 100644 --- a/apps/amm/qml/components/liquidity/NewPositionForm.qml +++ b/apps/amm/qml/components/liquidity/NewPositionForm.qml @@ -259,6 +259,7 @@ AmmActionCard { ? root.minimumAmountText("A") : "" errorText: root.formErrorText() invalid: root.fieldHasError("amountA") + || root.fieldHasError("holdingAId") readOnly: root.submitting || (!root.activePool && !root.missingPool) showMaxButton: root.activePool tokenData: root.tokenA.definitionId ? root.tokenA : null @@ -314,6 +315,7 @@ AmmActionCard { helperText: root.missingPool && !root.compact ? root.minimumAmountText("B") : "" invalid: root.fieldHasError("amountB") + || root.fieldHasError("holdingBId") readOnly: root.submitting || (!root.activePool && !root.missingPool) showMaxButton: root.activePool tokenData: root.tokenB.definitionId ? root.tokenB : null @@ -1233,20 +1235,30 @@ AmmActionCard { return root.displayIsCanonical ? "amountA" : "amountB" if (field === "amountBRaw") return root.displayIsCanonical ? "amountB" : "amountA" + if (field === "holdingAId") + return root.displayIsCanonical ? "holdingAId" : "holdingBId" + if (field === "holdingBId") + return root.displayIsCanonical ? "holdingBId" : "holdingAId" if (field === "initialPriceRealRaw") return "initialPrice" return field } function fieldError(field) { - var collections = [root.localErrors, root.currentQuoteErrors()] - for (var c = 0; c < collections.length; ++c) { - for (var i = 0; i < collections[c].length; ++i) { - var fields = collections[c][i].blockingFields || [] - for (var f = 0; f < fields.length; ++f) { - if (root.canonicalFieldToDisplay(fields[f]) === field) - return root.issueText(collections[c][i].code) - } + var localError = root.errorForField(root.localErrors, field, false) + return localError.length > 0 + ? localError + : root.errorForField(root.currentQuoteErrors(), field, true) + } + + function errorForField(errors, field, mapCanonicalField) { + for (var i = 0; i < errors.length; ++i) { + var fields = errors[i].blockingFields || [] + for (var f = 0; f < fields.length; ++f) { + var candidate = mapCanonicalField + ? root.canonicalFieldToDisplay(fields[f]) : fields[f] + if (candidate === field) + return root.issueText(errors[i].code) } } return "" diff --git a/apps/amm/tests/qml/tst_NewPositionForm.qml b/apps/amm/tests/qml/tst_NewPositionForm.qml index 1d74299..660aeeb 100644 --- a/apps/amm/tests/qml/tst_NewPositionForm.qml +++ b/apps/amm/tests/qml/tst_NewPositionForm.qml @@ -183,6 +183,21 @@ TestCase { "44444444444444444444444444444444") } + function test_holdingSelectionErrorMarksTheInputThatNeedsSelection() { + var form = createForm(holdingContext()) + var amountAInput = findChild(form, "tokenAAmountInput") + var amountBInput = findChild(form, "tokenBAmountInput") + verify(amountAInput) + verify(amountBInput) + + verify(!form.buildQuoteRequest().ok) + + compare(amountAInput.errorText, + form.issueText("holding_selection_required")) + verify(!amountAInput.invalid) + verify(amountBInput.invalid) + } + function test_contextRefreshSelectsSingleHoldingsBeforeQuote() { var form = createForm() form.selectedHoldingAId = ""