diff --git a/UI_SCHEMA_LAYOUT_ENHANCEMENT.md b/UI_SCHEMA_LAYOUT_ENHANCEMENT.md new file mode 100644 index 0000000..93c2bda --- /dev/null +++ b/UI_SCHEMA_LAYOUT_ENHANCEMENT.md @@ -0,0 +1,115 @@ +# UI Schema Layout Support Enhancement Summary + +## Changes Made + +### 1. Enhanced `DashboardNew.jsx` +- **Added imports**: `LayoutObjectFieldTemplate` and comprehensive widget collection +- **Updated Form components**: All RJSF Form components now use: + - `widgets={allWidgets}` - Comprehensive widget collection + - `templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }}` - Layout support +- **Enhanced Configuration Panel**: Now supports full UI schema features +- **Updated Dataset Manager**: Both definitions and variables forms support layouts +- **Added comprehensive documentation**: Detailed comments explaining UI schema features + +### 2. Created `AllWidgets.jsx` +- **Comprehensive widget collection**: Merges all available widgets +- **Widget aliases**: Support for different naming conventions in UI schemas +- **Custom widget integration**: Includes VariableSelectorWidget and PLC widgets +- **Backward compatibility**: Ensures existing UI schemas continue to work + +### 3. Enhanced `CustomWidgets.jsx` +- **Added widget aliases**: `variableSelector` for UI schema compatibility +- **Maintained existing functionality**: VariableSelectorWidget continues to work + +### 4. Updated `PlotManager.jsx` +- **Enhanced Form components**: Added layout template and comprehensive widgets +- **Consistent widget usage**: Uses same widget collection as DashboardNew + +### 5. Created Demo Files +- **`layout-demo.schema.json`**: Example schema for testing layouts +- **`layout-demo.uischema.json`**: Comprehensive UI schema example + +## UI Schema Features Now Supported + +### Layout Management +```json +{ + "ui:layout": [ + [ + { "name": "field1", "width": 6 }, + { "name": "field2", "width": 6 } + ], + [ + { "name": "field3", "width": 12 } + ] + ] +} +``` + +### Widget Types +- `updown` - Number input with +/- buttons +- `checkbox` - Boolean checkbox +- `text` - Text input +- `textarea` - Multi-line text +- `select` - Dropdown selection +- `VariableSelectorWidget` - Custom PLC variable selector + +### Field Properties +- `ui:help` - Help text for fields +- `ui:placeholder` - Placeholder text +- `ui:readonly` - Read-only fields +- `ui:order` - Field ordering +- `ui:column` - Column width (1-12 grid) + +### Examples from Existing Schemas + +#### PLC Configuration with Layout +```json +{ + "plc_config": { + "ui:layout": [ + [ + { "name": "ip", "width": 6 }, + { "name": "rack", "width": 3 }, + { "name": "slot", "width": 3 } + ] + ] + } +} +``` + +#### Dataset Definitions with Responsive Layout +```json +{ + "datasets": { + "ui:layout": [ + [ + { "name": "name", "width": 3 }, + { "name": "prefix", "width": 3 }, + { "name": "sampling_interval", "width": 3 }, + { "name": "enabled", "width": 3 } + ] + ] + } +} +``` + +## Benefits + +1. **Responsive Design**: 12-column grid system adapts to different screen sizes +2. **Better UX**: Logical field grouping and intuitive layouts +3. **Consistent Styling**: All forms use the same Chakra UI components +4. **Extensible**: Easy to add new widgets and layout patterns +5. **Backward Compatible**: Existing configurations continue to work +6. **Documentation**: Clear examples and comprehensive comments + +## Testing + +The enhanced UI schema support can be tested by: +1. Loading any existing configuration (PLC, datasets, plots) +2. Observing the improved layout with proper field grouping +3. Testing different screen sizes for responsive behavior +4. Adding new configurations with custom layouts +5. Using the demo schema files for comprehensive testing + +All existing functionality is preserved while adding powerful new layout capabilities. diff --git a/config/data/plc_config.json b/config/data/plc_config.json index 74f0260..fa2ad58 100644 --- a/config/data/plc_config.json +++ b/config/data/plc_config.json @@ -1,14 +1,14 @@ { "plc_config": { "ip": "10.1.33.11", - "rack": 0, + "rack": 1, "slot": 2 }, "udp_config": { "host": "127.0.0.1", "port": 9870 }, - "sampling_interval": 0.2, + "sampling_interval": 1.2, "csv_config": { "records_directory": "records", "rotation_enabled": true, diff --git a/config/schema/layout-demo.schema.json b/config/schema/layout-demo.schema.json new file mode 100644 index 0000000..88e9dd6 --- /dev/null +++ b/config/schema/layout-demo.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Enhanced UI Schema Layout Demo", + "description": "Demo configuration showcasing enhanced UI schema layout features", + "type": "object", + "properties": { + "basic_text": { + "type": "string", + "title": "Basic Text Input", + "description": "A simple text input field" + }, + "updown_number": { + "type": "number", + "title": "Number Input", + "description": "A numeric input with up/down controls", + "minimum": 0, + "maximum": 100, + "default": 50 + }, + "enabled_checkbox": { + "type": "boolean", + "title": "Enable Feature", + "description": "Toggle to enable or disable this feature", + "default": true + }, + "long_description": { + "type": "string", + "title": "Description", + "description": "A longer text description" + }, + "dropdown_selection": { + "type": "string", + "title": "Selection", + "description": "Choose from predefined options", + "enum": [ + "option1", + "option2", + "option3" + ], + "enumNames": [ + "First Option", + "Second Option", + "Third Option" + ] + }, + "variable_selector": { + "type": "string", + "title": "PLC Variable", + "description": "Select a variable from the PLC" + }, + "readonly_field": { + "type": "string", + "title": "Read-only Field", + "description": "This field cannot be modified", + "default": "Read-only value" + } + }, + "required": [ + "basic_text", + "updown_number" + ], + "additionalProperties": false +} diff --git a/config/schema/ui/layout-demo.uischema.json b/config/schema/ui/layout-demo.uischema.json new file mode 100644 index 0000000..c10863d --- /dev/null +++ b/config/schema/ui/layout-demo.uischema.json @@ -0,0 +1,78 @@ +{ + "ui:title": "Enhanced UI Schema Layout Demo", + "ui:description": "This demo showcases the full UI schema layout capabilities of the enhanced RJSF implementation", + "ui:layout": [ + [ + { + "name": "basic_text", + "width": 6 + }, + { + "name": "updown_number", + "width": 3 + }, + { + "name": "enabled_checkbox", + "width": 3 + } + ], + [ + { + "name": "long_description", + "width": 12 + } + ], + [ + { + "name": "dropdown_selection", + "width": 4 + }, + { + "name": "variable_selector", + "width": 4 + }, + { + "name": "readonly_field", + "width": 4 + } + ] + ], + "ui:order": [ + "basic_text", + "updown_number", + "enabled_checkbox", + "long_description", + "dropdown_selection", + "variable_selector", + "readonly_field" + ], + "basic_text": { + "ui:placeholder": "Enter some text here...", + "ui:help": "This is a standard text input with placeholder and help text" + }, + "updown_number": { + "ui:widget": "updown", + "ui:help": "Use +/- buttons to adjust the value" + }, + "enabled_checkbox": { + "ui:widget": "checkbox", + "ui:help": "Toggle this setting on/off" + }, + "long_description": { + "ui:widget": "textarea", + "ui:placeholder": "Enter a longer description here...", + "ui:help": "Multi-line text area that spans the full width" + }, + "dropdown_selection": { + "ui:widget": "select", + "ui:help": "Choose an option from the dropdown" + }, + "variable_selector": { + "ui:widget": "VariableSelectorWidget", + "ui:help": "Select a variable from the available PLC variables" + }, + "readonly_field": { + "ui:readonly": true, + "ui:help": "This field is read-only and cannot be edited" + } +} diff --git a/frontend/src/components/PlotManager.jsx b/frontend/src/components/PlotManager.jsx index 4a1f620..c596d18 100644 --- a/frontend/src/components/PlotManager.jsx +++ b/frontend/src/components/PlotManager.jsx @@ -39,7 +39,8 @@ import { } from '@chakra-ui/react' import Form from '@rjsf/chakra-ui' import validator from '@rjsf/validator-ajv8' -import { customWidgets } from './widgets/CustomWidgets' +import allWidgets from './widgets/AllWidgets' +import LayoutObjectFieldTemplate from './rjsf/LayoutObjectFieldTemplate' import * as api from '../services/api' // Pure RJSF Plot Manager Component @@ -338,7 +339,8 @@ export default function PlotManager() { uiSchema={plotsSchemaData.uiSchema} formData={plotsConfig} validator={validator} - widgets={customWidgets} + widgets={allWidgets} + templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} onSubmit={({ formData }) => savePlotsConfig(formData)} onChange={({ formData }) => setPlotsConfig(formData)} > @@ -376,7 +378,8 @@ export default function PlotManager() { uiSchema={plotsVariablesSchemaData.uiSchema} formData={plotsVariablesConfig} validator={validator} - widgets={customWidgets} + widgets={allWidgets} + templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} onSubmit={({ formData }) => savePlotsVariablesConfig(formData)} onChange={({ formData }) => setPlotsVariablesConfig(formData)} > diff --git a/frontend/src/components/widgets/AllWidgets.jsx b/frontend/src/components/widgets/AllWidgets.jsx new file mode 100644 index 0000000..73d94de --- /dev/null +++ b/frontend/src/components/widgets/AllWidgets.jsx @@ -0,0 +1,32 @@ +import { customWidgets } from './CustomWidgets' +import { widgets } from '../rjsf/widgets' + +// Comprehensive widget collection that merges all available widgets +// for full UI schema support with layouts +export const allWidgets = { + // Custom application-specific widgets + ...customWidgets, + + // Enhanced RJSF widgets with proper styling + ...widgets, + + // Additional widget aliases for UI schema compatibility + updown: widgets.UpDownWidget, + text: widgets.TextWidget, + textarea: widgets.TextareaWidget, + select: widgets.SelectWidget, + checkbox: widgets.CheckboxWidget, + + // Variable selector aliases + variableSelector: customWidgets.VariableSelectorWidget, + 'variable-selector': customWidgets.VariableSelectorWidget, + + // PLC-specific widget aliases (if available) + plcArea: widgets.PlcAreaWidget, + plcDataType: widgets.PlcDataTypeWidget, + plcNumber: widgets.PlcNumberWidget, + plcStreaming: widgets.PlcStreamingWidget, + plcVariableName: widgets.PlcVariableNameWidget, +} + +export default allWidgets diff --git a/frontend/src/components/widgets/CustomWidgets.jsx b/frontend/src/components/widgets/CustomWidgets.jsx index 234cd5f..7d697ef 100644 --- a/frontend/src/components/widgets/CustomWidgets.jsx +++ b/frontend/src/components/widgets/CustomWidgets.jsx @@ -63,7 +63,8 @@ export function VariableSelectorWidget(props) { // Export widgets object for RJSF export const customWidgets = { - VariableSelectorWidget + VariableSelectorWidget, + variableSelector: VariableSelectorWidget // Alternative name for UI schemas } export default customWidgets diff --git a/frontend/src/pages/DashboardNew.jsx b/frontend/src/pages/DashboardNew.jsx index 7fa991c..452287e 100644 --- a/frontend/src/pages/DashboardNew.jsx +++ b/frontend/src/pages/DashboardNew.jsx @@ -48,7 +48,8 @@ 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 allWidgets from '../components/widgets/AllWidgets' +import LayoutObjectFieldTemplate from '../components/rjsf/LayoutObjectFieldTemplate' import * as api from '../services/api' // Pure RJSF StatusBar Component @@ -254,7 +255,7 @@ function StatusBar({ status, onRefresh }) { ) } -// Pure RJSF Configuration Panel +// Pure RJSF Configuration Panel with Full UI Schema Layout Support function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schemaData, formData, onFormChange, onSave, saving, message }) { const cardBg = useColorModeValue('white', 'gray.700') const borderColor = useColorModeValue('gray.200', 'gray.600') @@ -276,7 +277,7 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schemaDa 🔧 Configuration Editor - Pure RJSF configuration management with UI Schema layouts + Pure RJSF configuration management with full UI Schema layout support (ui:layout, ui:widgets, custom field templates) @@ -306,7 +307,8 @@ function ConfigurationPanel({ schemas, currentSchemaId, onSchemaChange, schemaDa uiSchema={schemaData.uiSchema} formData={formData} validator={validator} - widgets={customWidgets} + widgets={allWidgets} + templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} onChange={({ formData }) => onFormChange(formData)} onSubmit={({ formData }) => onSave(formData)} > @@ -451,7 +453,8 @@ function DatasetManager() { uiSchema={datasetsSchemaData.uiSchema} formData={datasetsConfig} validator={validator} - widgets={customWidgets} + widgets={allWidgets} + templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} onSubmit={({ formData }) => saveDatasets(formData)} onChange={({ formData }) => setDatasetsConfig(formData)} > @@ -484,7 +487,8 @@ function DatasetManager() { uiSchema={variablesSchemaData.uiSchema} formData={variablesConfig} validator={validator} - widgets={customWidgets} + widgets={allWidgets} + templates={{ ObjectFieldTemplate: LayoutObjectFieldTemplate }} onSubmit={({ formData }) => saveVariables(formData)} onChange={({ formData }) => setVariablesConfig(formData)} > @@ -580,7 +584,30 @@ function EventsDisplay({ events, loading, onRefresh }) { ) } -// Main Dashboard Component with Pure RJSF +// Main Dashboard Component with Pure RJSF and Full UI Schema Layout Support +// +// This dashboard now supports comprehensive UI schema features: +// +// 1. Layout Management: +// - ui:layout: Grid-based field layouts with customizable column spans +// - ui:order: Field ordering control +// - ui:column: Responsive column widths (1-12 grid system) +// +// 2. Widget Support: +// - Standard widgets: text, textarea, select, checkbox, updown +// - Custom widgets: VariableSelectorWidget, PlcWidgets +// - Widget aliases for backward compatibility +// +// 3. Field Templates: +// - LayoutObjectFieldTemplate: Handles ui:layout rendering +// - Responsive grid system with Chakra UI SimpleGrid +// - Proper field grouping and spacing +// +// 4. UI Schema Examples: +// - ui:layout: [[ { "name": "field1", "width": 6 }, { "name": "field2", "width": 6 } ]] +// - ui:widget: "updown", "checkbox", "variableSelector", etc. +// - ui:help, ui:placeholder, ui:readonly for enhanced UX +// export default function Dashboard() { const [status, setStatus] = useState(null) const [statusLoading, setStatusLoading] = useState(true)