diff --git a/application_events.json b/application_events.json index d9a1279..deb6e63 100644 --- a/application_events.json +++ b/application_events.json @@ -10426,8 +10426,29 @@ "event_type": "application_started", "message": "Application initialization completed successfully", "details": {} + }, + { + "timestamp": "2025-08-13T15:49:35.843750", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-13T15:55:43.678603", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-13T16:02:51.706311", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} } ], - "last_updated": "2025-08-13T15:31:15.343148", - "total_entries": 988 + "last_updated": "2025-08-13T16:02:51.706311", + "total_entries": 991 } \ No newline at end of file diff --git a/frontend/src/components/PlotManager.jsx b/frontend/src/components/PlotManager.jsx index f52a41f..4a1f620 100644 --- a/frontend/src/components/PlotManager.jsx +++ b/frontend/src/components/PlotManager.jsx @@ -39,13 +39,14 @@ import { } from '@chakra-ui/react' import Form from '@rjsf/chakra-ui' import validator from '@rjsf/validator-ajv8' +import { customWidgets } from './widgets/CustomWidgets' import * as api from '../services/api' // Pure RJSF Plot Manager Component export default function PlotManager() { const [plots, setPlots] = useState({}) - const [plotsSchema, setPlotsSchema] = useState(null) - const [plotsVariablesSchema, setPlotsVariablesSchema] = useState(null) + const [plotsSchemaData, setPlotsSchemaData] = useState(null) + const [plotsVariablesSchemaData, setPlotsVariablesSchemaData] = useState(null) const [plotsConfig, setPlotsConfig] = useState(null) const [plotsVariablesConfig, setPlotsVariablesConfig] = useState(null) const [loading, setLoading] = useState(true) @@ -68,8 +69,8 @@ export default function PlotManager() { setLoading(true) const [ plotsData, - plotsSchemaData, - plotsVariablesSchemaData, + plotsSchemaResponse, + plotsVariablesSchemaResponse, plotsConfigData, plotsVariablesConfigData ] = await Promise.all([ @@ -81,8 +82,8 @@ export default function PlotManager() { ]) setPlots(plotsData?.plots || {}) - setPlotsSchema(plotsSchemaData) - setPlotsVariablesSchema(plotsVariablesSchemaData) + setPlotsSchemaData(plotsSchemaResponse) + setPlotsVariablesSchemaData(plotsVariablesSchemaResponse) setPlotsConfig(plotsConfigData) setPlotsVariablesConfig(plotsVariablesConfigData) } catch (error) { @@ -323,7 +324,7 @@ export default function PlotManager() { - {plotsSchema && plotsConfig && ( + {plotsSchemaData?.schema && plotsConfig && ( Plot Session Definitions @@ -333,9 +334,11 @@ export default function PlotManager() {
savePlotsConfig(formData)} onChange={({ formData }) => setPlotsConfig(formData)} > @@ -359,7 +362,7 @@ export default function PlotManager() { - {plotsVariablesSchema && plotsVariablesConfig && ( + {plotsVariablesSchemaData?.schema && plotsVariablesConfig && ( Plot Variables Configuration @@ -369,9 +372,11 @@ export default function PlotManager() { savePlotsVariablesConfig(formData)} onChange={({ formData }) => setPlotsVariablesConfig(formData)} > diff --git a/frontend/src/components/widgets/CustomWidgets.jsx b/frontend/src/components/widgets/CustomWidgets.jsx new file mode 100644 index 0000000..234cd5f --- /dev/null +++ b/frontend/src/components/widgets/CustomWidgets.jsx @@ -0,0 +1,69 @@ +import React, { useState, useEffect } from 'react' +import { Select } from '@chakra-ui/react' +import * as api from '../../services/api' + +// Custom Variable Selector Widget for RJSF +export function VariableSelectorWidget(props) { + const { value, onChange, options, placeholder, disabled, readonly } = props + const [variables, setVariables] = useState([]) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const loadVariables = async () => { + try { + setLoading(true) + // Try to get variables from plot variables API + const plotVariables = await api.getPlotVariables() + // Extract the available_variables array from the response + if (plotVariables && plotVariables.available_variables && Array.isArray(plotVariables.available_variables)) { + setVariables(plotVariables.available_variables) + } else { + console.warn('Unexpected plot variables response format:', plotVariables) + setVariables([]) + } + } catch (error) { + console.error('Failed to load variables:', error) + setVariables([]) + } finally { + setLoading(false) + } + } + + loadVariables() + }, []) + + const handleChange = (event) => { + onChange(event.target.value === '' ? undefined : event.target.value) + } + + if (loading) { + return ( + + ) + } + + return ( + + ) +} + +// Export widgets object for RJSF +export const customWidgets = { + VariableSelectorWidget +} + +export default customWidgets diff --git a/frontend/src/pages/DashboardNew.jsx b/frontend/src/pages/DashboardNew.jsx index d044839..7fa991c 100644 --- a/frontend/src/pages/DashboardNew.jsx +++ b/frontend/src/pages/DashboardNew.jsx @@ -48,6 +48,7 @@ import { import Form from '@rjsf/chakra-ui' import validator from '@rjsf/validator-ajv8' import PlotManager from '../components/PlotManager' +import { customWidgets } from '../components/widgets/CustomWidgets' import * as api from '../services/api' // Pure RJSF StatusBar Component @@ -254,11 +255,11 @@ function StatusBar({ status, onRefresh }) { } // Pure RJSF Configuration Panel -function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema, formData, onFormChange, onSave, saving, message }) { +function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schemaData, formData, onFormChange, onSave, saving, message }) { const cardBg = useColorModeValue('white', 'gray.700') const borderColor = useColorModeValue('gray.200', 'gray.600') - if (!schema || !formData) { + if (!schemaData?.schema || !formData) { return ( @@ -275,7 +276,7 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema, 🔧 Configuration Editor - Pure RJSF configuration management + Pure RJSF configuration management with UI Schema layouts @@ -301,9 +302,11 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema, onFormChange(formData)} onSubmit={({ formData }) => onSave(formData)} > @@ -330,15 +333,15 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema, function DatasetManager() { const [datasetsConfig, setDatasetsConfig] = useState(null) const [variablesConfig, setVariablesConfig] = useState(null) - const [datasetsSchema, setDatasetsSchema] = useState(null) - const [variablesSchema, setVariablesSchema] = useState(null) + const [datasetsSchemaData, setDatasetsSchemaData] = useState(null) + const [variablesSchemaData, setVariablesSchemaData] = useState(null) const [loading, setLoading] = useState(true) const toast = useToast() const loadDatasetData = async () => { try { setLoading(true) - const [datasetsData, variablesData, datasetsSchemaData, variablesSchemaData] = await Promise.all([ + const [datasetsData, variablesData, datasetsSchemaResponse, variablesSchemaResponse] = await Promise.all([ api.readConfig('dataset-definitions'), api.readConfig('dataset-variables'), api.getSchema('dataset-definitions'), @@ -347,8 +350,8 @@ function DatasetManager() { setDatasetsConfig(datasetsData) setVariablesConfig(variablesData) - setDatasetsSchema(datasetsSchemaData) - setVariablesSchema(variablesSchemaData) + setDatasetsSchemaData(datasetsSchemaResponse) + setVariablesSchemaData(variablesSchemaResponse) } catch (error) { toast({ title: '❌ Failed to load dataset data', @@ -434,7 +437,7 @@ function DatasetManager() { - {datasetsSchema && datasetsConfig && ( + {datasetsSchemaData?.schema && datasetsConfig && ( Dataset Metadata Configuration @@ -444,9 +447,11 @@ function DatasetManager() { saveDatasets(formData)} onChange={({ formData }) => setDatasetsConfig(formData)} > @@ -465,7 +470,7 @@ function DatasetManager() { - {variablesSchema && variablesConfig && ( + {variablesSchemaData?.schema && variablesConfig && ( Dataset Variables Configuration @@ -475,9 +480,11 @@ function DatasetManager() { saveVariables(formData)} onChange={({ formData }) => setVariablesConfig(formData)} > @@ -581,7 +588,7 @@ export default function Dashboard() { const [schemas, setSchemas] = useState([]) const [currentSchemaId, setCurrentSchemaId] = useState('plc') - const [schema, setSchema] = useState(null) + const [schemaData, setSchemaData] = useState(null) const [formData, setFormData] = useState(null) const [saving, setSaving] = useState(false) const [message, setMessage] = useState('') @@ -662,11 +669,11 @@ export default function Dashboard() { // Load specific config const loadConfig = useCallback(async (schemaId) => { try { - const [schemaData, configData] = await Promise.all([ + const [schemaResponse, configData] = await Promise.all([ api.getSchema(schemaId), api.readConfig(schemaId) ]) - setSchema(schemaData) + setSchemaData(schemaResponse) setFormData(configData) setMessage('') } catch (error) { @@ -763,7 +770,7 @@ export default function Dashboard() { schemas={schemas} currentSchemaId={currentSchemaId} onSchemaChange={setCurrentSchemaId} - schema={schema} + schemaData={schemaData} formData={formData} onFormChange={setFormData} onSave={saveConfig} diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 2dc4aa0..748d114 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -69,8 +69,11 @@ export async function getSchema(schemaId) { const res = await fetch(`${BASE_URL}/api/config/schema/${encodeURIComponent(schemaId)}`, { headers: { 'Accept': 'application/json' } }) const response = await toJsonOrThrow(res) // The API returns { success: true, schema: {...}, ui_schema?: {...} } - // We need to extract just the schema part for RJSF - return response.schema || response + // Return both schema and uiSchema for RJSF + return { + schema: response.schema || response, + uiSchema: response.ui_schema || {} + } } export async function readConfig(configId) {