fix: allow high precision for security prices in trade forms (to solve #1323) (#1342)

* fix: allow high precision for security prices in trade forms (to solve #1323)

* fix: prevent race conditions on currency selection in money field

* fix: silently ignore currency fetch errors in money field
This commit is contained in:
Louis
2026-04-07 12:19:17 +02:00
committed by GitHub
parent cebdf1d4f7
commit cc8d6ca2a0
3 changed files with 31 additions and 7 deletions

View File

@@ -1,11 +1,17 @@
import { Controller } from "@hotwired/stimulus";
import parseLocaleFloat from "utils/parse_locale_float";
import { CurrenciesService } from "services/currencies_service";
import parseLocaleFloat from "utils/parse_locale_float";
// Connects to data-controller="money-field"
// when currency select change, update the input value with the correct placeholder and step
export default class extends Controller {
static targets = ["amount", "currency", "symbol"];
static values = {
precision: Number,
step: String,
};
requestSequence = 0;
handleCurrencyChange(e) {
const selectedCurrency = e.target.value;
@@ -13,18 +19,33 @@ export default class extends Controller {
}
updateAmount(currency) {
new CurrenciesService().get(currency).then((currency) => {
this.amountTarget.step = currency.step;
const requestId = ++this.requestSequence;
new CurrenciesService().get(currency).then((currencyData) => {
if (requestId !== this.requestSequence) return;
this.amountTarget.step =
this.hasStepValue &&
this.stepValue !== "" &&
(this.stepValue === "any" || Number.isFinite(Number(this.stepValue)))
? this.stepValue
: currencyData.step;
const rawValue = this.amountTarget.value.trim();
if (rawValue !== "") {
const parsedAmount = parseLocaleFloat(rawValue);
if (Number.isFinite(parsedAmount)) {
this.amountTarget.value = parsedAmount.toFixed(currency.default_precision);
const precision =
this.hasPrecisionValue && Number.isInteger(this.precisionValue)
? this.precisionValue
: currencyData.default_precision;
this.amountTarget.value = parsedAmount.toFixed(precision);
}
}
this.symbolTarget.innerText = currency.symbol;
this.symbolTarget.innerText = currencyData.symbol;
}).catch(() => {
// Catch prevents Unhandled Promise Rejection for network failures.
// Silently ignored as they are unactionable by the user.
});
}
}