Fix: Support floating point numbers in settings (Consensus Quorum Threshold)

Changed number type settings parsing from parseInt to parseFloat to
properly handle decimal values. Added step="any" attribute to number
inputs in the frontend when the setting has decimal min/max/default
values.

This ensures that Consensus Quorum Threshold and other floating point
settings (like METRICS_SAMPLING_RATE) can accept and save decimal
values like 0.5, 0.67, etc. instead of being truncated to integers.

- Updated includes/admin/admin-backend/routes/settings.js
- Updated includes/admin/routes/settings.js
- Updated includes/admin/admin-frontend/ui/settings.js
This commit is contained in:
Raven Scott
2025-12-26 21:20:58 -05:00
parent c4fd25c17e
commit 398e042e81
4 changed files with 16 additions and 3 deletions
@@ -229,7 +229,9 @@ async function handleSettingsRoutes(req, res) {
const meta = settingsMetadata[key];
if (meta) {
if (meta.type === 'number') {
const numValue = parseInt(value, 10);
// Use parseFloat to support both integers and floating point numbers
// parseFloat works for integers too (e.g., parseFloat("5") returns 5)
const numValue = parseFloat(value);
if (isNaN(numValue)) {
errors.push(`${meta.label}: must be a number`);
continue;
+7 -1
View File
@@ -236,8 +236,14 @@ async function renderSettings(data) {
} else if (inputType === 'number') {
const min = meta?.min !== undefined ? `min="${meta.min}"` : '';
const max = meta?.max !== undefined ? `max="${meta.max}"` : '';
// Add step attribute for floating point numbers
// Check if min or max has decimal part, or if default value suggests it's a float
const hasDecimal = (meta?.min !== undefined && meta.min % 1 !== 0) ||
(meta?.max !== undefined && meta.max % 1 !== 0) ||
(meta?.default && parseFloat(meta.default) % 1 !== 0);
const step = hasDecimal ? `step="any"` : '';
inputHtml = `
<input type="number" data-key="${key}" value="${value || defaultValue}" ${min} ${max}
<input type="number" data-key="${key}" value="${value || defaultValue}" ${min} ${max} ${step}
class="w-full p-2 border border-gray-300 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary">
`;
} else {
+3 -1
View File
@@ -187,7 +187,9 @@ async function handleSettingsRoutes(req, res) {
const meta = settingsMetadata[key];
if (meta) {
if (meta.type === 'number') {
const numValue = parseInt(value, 10);
// Use parseFloat to support both integers and floating point numbers
// parseFloat works for integers too (e.g., parseFloat("5") returns 5)
const numValue = parseFloat(value);
if (isNaN(numValue)) {
errors.push(`${meta.label}: must be a number`);
continue;
+3
View File
@@ -67,3 +67,6 @@ async function setupDatabaseWatcher() {
module.exports = {
setupDatabaseWatcher
};