diff --git a/dashboard/frontend/src/App.tsx b/dashboard/frontend/src/App.tsx index 82c7b150..675f34ea 100644 --- a/dashboard/frontend/src/App.tsx +++ b/dashboard/frontend/src/App.tsx @@ -5,9 +5,11 @@ import LandingPage from './pages/LandingPage' import MonitoringPage from './pages/MonitoringPage' import ConfigPage from './pages/ConfigPage' import PlaygroundPage from './pages/PlaygroundPage' +import { ConfigSection } from './components/ConfigNav' const App: React.FC = () => { const [isInIframe, setIsInIframe] = useState(false) + const [configSection, setConfigSection] = useState('models') useEffect(() => { // Detect if we're running inside an iframe (potential loop) @@ -70,9 +72,39 @@ const App: React.FC = () => { } /> - } /> - } /> - } /> + setConfigSection(section as ConfigSection)} + > + + + } + /> + setConfigSection(section as ConfigSection)} + > + + + } + /> + setConfigSection(section as ConfigSection)} + > + + + } + /> ) diff --git a/dashboard/frontend/src/components/EditModal.tsx b/dashboard/frontend/src/components/EditModal.tsx index c9fb89f5..bb3887f3 100644 --- a/dashboard/frontend/src/components/EditModal.tsx +++ b/dashboard/frontend/src/components/EditModal.tsx @@ -14,11 +14,14 @@ interface EditModalProps { export interface FieldConfig { name: string label: string - type: 'text' | 'number' | 'boolean' | 'select' | 'multiselect' | 'textarea' | 'json' + type: 'text' | 'number' | 'boolean' | 'select' | 'multiselect' | 'textarea' | 'json' | 'percentage' required?: boolean options?: string[] placeholder?: string description?: string + min?: number + max?: number + step?: number } const EditModal: React.FC = ({ @@ -36,10 +39,17 @@ const EditModal: React.FC = ({ useEffect(() => { if (isOpen) { - setFormData(data || {}) + // Convert percentage fields from 0-1 to 0-100 for display + const convertedData = { ...data } + fields.forEach(field => { + if (field.type === 'percentage' && convertedData[field.name] !== undefined) { + convertedData[field.name] = Math.round(convertedData[field.name] * 100) + } + }) + setFormData(convertedData || {}) setError(null) } - }, [isOpen, data]) + }, [isOpen, data, fields]) const handleChange = (fieldName: string, value: any) => { setFormData((prev: any) => ({ @@ -54,7 +64,14 @@ const EditModal: React.FC = ({ setError(null) try { - await onSave(formData) + // Convert percentage fields from 0-100 back to 0-1 before saving + const convertedData = { ...formData } + fields.forEach(field => { + if (field.type === 'percentage' && convertedData[field.name] !== undefined) { + convertedData[field.name] = convertedData[field.name] / 100 + } + }) + await onSave(convertedData) onClose() } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save') @@ -106,7 +123,9 @@ const EditModal: React.FC = ({ {field.type === 'number' && ( handleChange(field.name, parseFloat(e.target.value))} @@ -115,6 +134,37 @@ const EditModal: React.FC = ({ /> )} + {field.type === 'percentage' && ( +
+ { + const val = e.target.value + handleChange(field.name, val === '' ? '' : parseFloat(val)) + }} + placeholder={field.placeholder} + required={field.required} + style={{ paddingRight: '2.5rem' }} + /> + + % + +
+ )} + {field.type === 'boolean' && (