Enhance event logging in application_events.json and update last_updated and total_entries fields. Refactor PlotManager and Dashboard components to utilize schemaData and uiSchema, improving configuration management. Introduce custom widgets for RJSF, including a VariableSelectorWidget for dynamic variable selection.
This commit is contained in:
parent
4af442e3e8
commit
e6ccb19fd2
|
@ -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
|
||||
}
|
|
@ -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() {
|
|||
|
||||
<TabPanels>
|
||||
<TabPanel p={0} pt={4}>
|
||||
{plotsSchema && plotsConfig && (
|
||||
{plotsSchemaData?.schema && plotsConfig && (
|
||||
<Card bg={cardBg} borderColor={borderColor}>
|
||||
<CardHeader>
|
||||
<Heading size="md">Plot Session Definitions</Heading>
|
||||
|
@ -333,9 +334,11 @@ export default function PlotManager() {
|
|||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form
|
||||
schema={plotsSchema}
|
||||
schema={plotsSchemaData.schema}
|
||||
uiSchema={plotsSchemaData.uiSchema}
|
||||
formData={plotsConfig}
|
||||
validator={validator}
|
||||
widgets={customWidgets}
|
||||
onSubmit={({ formData }) => savePlotsConfig(formData)}
|
||||
onChange={({ formData }) => setPlotsConfig(formData)}
|
||||
>
|
||||
|
@ -359,7 +362,7 @@ export default function PlotManager() {
|
|||
</TabPanel>
|
||||
|
||||
<TabPanel p={0} pt={4}>
|
||||
{plotsVariablesSchema && plotsVariablesConfig && (
|
||||
{plotsVariablesSchemaData?.schema && plotsVariablesConfig && (
|
||||
<Card bg={cardBg} borderColor={borderColor}>
|
||||
<CardHeader>
|
||||
<Heading size="md">Plot Variables Configuration</Heading>
|
||||
|
@ -369,9 +372,11 @@ export default function PlotManager() {
|
|||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form
|
||||
schema={plotsVariablesSchema}
|
||||
schema={plotsVariablesSchemaData.schema}
|
||||
uiSchema={plotsVariablesSchemaData.uiSchema}
|
||||
formData={plotsVariablesConfig}
|
||||
validator={validator}
|
||||
widgets={customWidgets}
|
||||
onSubmit={({ formData }) => savePlotsVariablesConfig(formData)}
|
||||
onChange={({ formData }) => setPlotsVariablesConfig(formData)}
|
||||
>
|
||||
|
|
|
@ -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 (
|
||||
<Select placeholder="Loading variables..." disabled>
|
||||
<option value="">Loading...</option>
|
||||
</Select>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Select
|
||||
value={value || ''}
|
||||
onChange={handleChange}
|
||||
placeholder={placeholder || 'Select a variable...'}
|
||||
disabled={disabled || readonly}
|
||||
>
|
||||
<option value="">-- Select Variable --</option>
|
||||
{Array.isArray(variables) && variables.map((variable, index) => (
|
||||
<option key={variable.name || index} value={variable.name || variable}>
|
||||
{variable.display_name || variable.name || variable}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
)
|
||||
}
|
||||
|
||||
// Export widgets object for RJSF
|
||||
export const customWidgets = {
|
||||
VariableSelectorWidget
|
||||
}
|
||||
|
||||
export default customWidgets
|
|
@ -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 (
|
||||
<Card bg={cardBg} borderColor={borderColor}>
|
||||
<CardBody>
|
||||
|
@ -275,7 +276,7 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema,
|
|||
<Box>
|
||||
<Heading size="md">🔧 Configuration Editor</Heading>
|
||||
<Text fontSize="sm" color="gray.500" mt={1}>
|
||||
Pure RJSF configuration management
|
||||
Pure RJSF configuration management with UI Schema layouts
|
||||
</Text>
|
||||
</Box>
|
||||
<Spacer />
|
||||
|
@ -301,9 +302,11 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schema,
|
|||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form
|
||||
schema={schema}
|
||||
schema={schemaData.schema}
|
||||
uiSchema={schemaData.uiSchema}
|
||||
formData={formData}
|
||||
validator={validator}
|
||||
widgets={customWidgets}
|
||||
onChange={({ formData }) => 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() {
|
|||
|
||||
<TabPanels>
|
||||
<TabPanel p={0} pt={4}>
|
||||
{datasetsSchema && datasetsConfig && (
|
||||
{datasetsSchemaData?.schema && datasetsConfig && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Heading size="md">Dataset Metadata Configuration</Heading>
|
||||
|
@ -444,9 +447,11 @@ function DatasetManager() {
|
|||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form
|
||||
schema={datasetsSchema}
|
||||
schema={datasetsSchemaData.schema}
|
||||
uiSchema={datasetsSchemaData.uiSchema}
|
||||
formData={datasetsConfig}
|
||||
validator={validator}
|
||||
widgets={customWidgets}
|
||||
onSubmit={({ formData }) => saveDatasets(formData)}
|
||||
onChange={({ formData }) => setDatasetsConfig(formData)}
|
||||
>
|
||||
|
@ -465,7 +470,7 @@ function DatasetManager() {
|
|||
</TabPanel>
|
||||
|
||||
<TabPanel p={0} pt={4}>
|
||||
{variablesSchema && variablesConfig && (
|
||||
{variablesSchemaData?.schema && variablesConfig && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Heading size="md">Dataset Variables Configuration</Heading>
|
||||
|
@ -475,9 +480,11 @@ function DatasetManager() {
|
|||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form
|
||||
schema={variablesSchema}
|
||||
schema={variablesSchemaData.schema}
|
||||
uiSchema={variablesSchemaData.uiSchema}
|
||||
formData={variablesConfig}
|
||||
validator={validator}
|
||||
widgets={customWidgets}
|
||||
onSubmit={({ formData }) => 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}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue