Files
LEDMatrix/docs/PLUGIN_CONFIGURATION_TABS.md
Chuck b374bfa8c6 docs: fix plugin config + store + dependency docs
PLUGIN_STORE_GUIDE.md
- 19 occurrences of port 5050 -> 5000
- All API paths missing /v3 (e.g. /api/plugins/install ->
  /api/v3/plugins/install). Bulk fix.

PLUGIN_REGISTRY_SETUP_GUIDE.md
- Same port + /api/v3 fixes (3 occurrences each)
- "Go to Plugin Store tab" -> "Open the Plugin Manager tab and scroll
  to the Install from GitHub section" (the real flow for registry
  setup is the GitHub install section, not the Plugin Store search)

PLUGIN_CONFIG_QUICK_START.md
- Port 5001 -> 5000 (5001 is the dev_server.py default, not the web UI)
- "Plugin Store tab" install flow -> real Plugin Manager + Plugin Store
  section + per-plugin tab in second nav row
- Removed reference to PLUGIN_CONFIG_TABS_SUMMARY.md (archived doc)

PLUGIN_CONFIGURATION_TABS.md
- "Plugin Management vs Configuration" section confusingly described
  a "Plugins Tab" that doesn't exist as a single thing. Rewrote to
  describe the real two-piece structure: Plugin Manager tab (browse,
  install, toggle) vs per-plugin tabs (configure individual plugins).

PLUGIN_DEPENDENCY_GUIDE.md
- Port 5001 -> 5000

PLUGIN_DEPENDENCY_TROUBLESHOOTING.md
- Wrong port (8080) and wrong UI nav ("Plugin Store or Plugin
  Management"). Fixed to the real flow.

PLUGIN_QUICK_REFERENCE.md
- "Plugin Location: ./plugins/ directory" -> default is plugin-repos/
  (verified in config/config.template.json:130 and
  display_controller.py:132). plugins/ is a fallback.
- File structure diagram showed plugins/ -> plugin-repos/.
- Web UI install flow: "Plugin Store tab" -> "Plugin Manager tab ->
  Plugin Store section". Also fixed Configure ⚙️ button (doesn't
  exist) and "Drag and drop reorder" (not implemented).
- API examples: replaced ad-hoc Python pseudocode with real curl
  examples against /api/v3/plugins/* endpoints. Pointed at
  REST_API_REFERENCE.md for the full list.
- "Migration Path Phase 1-5" was a roadmap written before the plugin
  system shipped. The plugin system is now stable and live. Removed
  the migration phases as they're history, not a roadmap.
- "Quick Migration" section called scripts/migrate_to_plugins.py
  which doesn't exist anywhere in the repo. Removed.
- "Plugin Registry Structure" referenced
  ChuckBuilds/ledmatrix-plugin-registry which doesn't exist. The
  real registry is ChuckBuilds/ledmatrix-plugins. Fixed.
- "Next Steps" / "Questions to Resolve" sections were
  pre-implementation planning notes. Replaced with a "Known
  Limitations" section that documents the actually-real gaps
  (sandboxing, resource limits, ratings, auto-updates).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:10:05 -04:00

329 lines
8.9 KiB
Markdown

# Plugin Configuration Tabs
## Overview
Each installed plugin now gets its own dedicated configuration tab in the web interface. This provides a clean, organized way to configure plugins without cluttering the main Plugins management tab.
## Features
- **Automatic Tab Generation**: When a plugin is installed, a new tab is automatically created in the web UI
- **JSON Schema-Based Forms**: Configuration forms are automatically generated based on each plugin's `config_schema.json`
- **Type-Safe Inputs**: Form inputs are created based on the JSON Schema type (boolean, number, string, array, enum)
- **Default Values**: All fields show current values or fallback to schema defaults
- **Reset Functionality**: Users can reset all settings to defaults with one click
- **Real-Time Validation**: Input constraints from JSON Schema are enforced (min, max, maxLength, etc.)
## User Experience
### Accessing Plugin Configuration
1. Navigate to the **Plugins** tab to see all installed plugins
2. Click the **Configure** button on any plugin card
3. You'll be automatically taken to that plugin's configuration tab
4. Alternatively, click directly on the plugin's tab button (marked with a puzzle piece icon)
### Configuring a Plugin
1. Open the plugin's configuration tab
2. Modify settings using the generated form
3. Click **Save Configuration**
4. Restart the display service to apply changes
### Plugin Manager vs Per-Plugin Configuration
- **Plugin Manager tab** (second nav row): used for browsing the
Plugin Store, installing plugins, toggling installed plugins on/off,
and updating/uninstalling them
- **Per-plugin tabs** (one per installed plugin, also in the second
nav row): used for configuring that specific plugin's behavior and
settings via a form auto-generated from its `config_schema.json`
## For Plugin Developers
### Requirements
To enable automatic configuration tab generation, your plugin must:
1. Include a `config_schema.json` file
2. Reference it in your `manifest.json`:
```json
{
"id": "your-plugin",
"name": "Your Plugin",
"icon": "fas fa-star", // Optional: Custom tab icon
...
"config_schema": "config_schema.json"
}
```
**Note:** You can optionally specify a custom `icon` for your plugin tab. See [Plugin Custom Icons Guide](PLUGIN_CUSTOM_ICONS.md) for details.
### Supported JSON Schema Types
The form generator supports the following JSON Schema types:
#### Boolean
```json
{
"type": "boolean",
"default": true,
"description": "Enable or disable this feature"
}
```
Renders as: Toggle switch
#### Number / Integer
```json
{
"type": "integer",
"default": 60,
"minimum": 1,
"maximum": 300,
"description": "Update interval in seconds"
}
```
Renders as: Number input with min/max constraints
#### String
```json
{
"type": "string",
"default": "Hello, World!",
"minLength": 1,
"maxLength": 50,
"description": "The message to display"
}
```
Renders as: Text input with length constraints
#### Array
```json
{
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3,
"default": [255, 255, 255],
"description": "RGB color [R, G, B]"
}
```
Renders as: Text input (comma-separated values)
Example input: `255, 128, 0`
#### Enum (Select)
```json
{
"type": "string",
"enum": ["small", "medium", "large"],
"default": "medium",
"description": "Display size"
}
```
Renders as: Dropdown select
### Example config_schema.json
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "My Plugin Configuration",
"description": "Configure my awesome plugin",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable or disable this plugin"
},
"message": {
"type": "string",
"default": "Hello!",
"minLength": 1,
"maxLength": 50,
"description": "The message to display"
},
"update_interval": {
"type": "integer",
"default": 60,
"minimum": 1,
"maximum": 3600,
"description": "Update interval in seconds"
},
"color": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3,
"default": [255, 255, 255],
"description": "RGB color [R, G, B]"
},
"mode": {
"type": "string",
"enum": ["scroll", "static", "fade"],
"default": "scroll",
"description": "Display mode"
}
},
"required": ["enabled"],
"additionalProperties": false
}
```
### Best Practices
1. **Use Descriptive Labels**: The `description` field is shown as help text under each input
2. **Set Sensible Defaults**: Always provide default values that work out of the box
3. **Use Constraints**: Leverage min/max, minLength/maxLength to guide users
4. **Mark Required Fields**: Use the `required` array in your schema
5. **Organize Properties**: List properties in order of importance
### Form Generation Process
1. Web UI loads installed plugins via `/api/plugins/installed`
2. For each plugin, the backend loads its `config_schema.json`
3. Frontend generates a tab button with plugin name
4. Frontend generates a form based on the JSON Schema
5. Current config values from `config.json` are populated
6. When saved, each field is sent to `/api/plugins/config` endpoint
## Implementation Details
### Backend Changes
**File**: `web_interface_v2.py`
- Modified `/api/plugins/installed` endpoint to include `config_schema_data`
- Loads each plugin's `config_schema.json` if it exists
- Returns schema data along with plugin info
### Frontend Changes
**File**: `templates/index_v2.html`
New Functions:
- `generatePluginTabs(plugins)` - Creates tab buttons and content for each plugin
- `generatePluginConfigForm(plugin)` - Generates HTML form from JSON Schema
- `savePluginConfiguration(pluginId)` - Saves form data to backend
- `resetPluginConfig(pluginId)` - Resets all settings to defaults
- `configurePlugin(pluginId)` - Navigates to plugin's tab
### Data Flow
```
Page Load
→ refreshPlugins()
→ /api/plugins/installed
→ Returns plugins with config_schema_data
→ generatePluginTabs()
→ Creates tab buttons
→ Creates tab content
→ generatePluginConfigForm()
→ Reads JSON Schema
→ Creates form inputs
→ Populates current values
User Saves
→ savePluginConfiguration()
→ Reads form data
→ Converts types per schema
→ Sends to /api/plugins/config
→ Updates config.json
→ Shows success notification
```
## Troubleshooting
### Plugin Tab Not Appearing
- Ensure `config_schema.json` exists in plugin directory
- Verify `config_schema` field in `manifest.json`
- Check browser console for errors
- Try refreshing plugins (Plugins tab → Refresh button)
### Form Not Generating Correctly
- Validate your `config_schema.json` against JSON Schema Draft 07
- Check that all properties have a `type` field
- Ensure `default` values match the specified type
- Look for JavaScript errors in browser console
### Configuration Not Saving
- Ensure the plugin is properly installed
- Check that config keys match schema properties
- Verify backend API is accessible
- Check browser network tab for API errors
- Ensure display service is restarted after config changes
## Migration Guide
### For Existing Plugins
If your plugin already has a `config_schema.json`:
1. No changes needed! The tab will be automatically generated.
2. Test the generated form to ensure all fields render correctly.
3. Consider adding more descriptive `description` fields.
If your plugin doesn't have a config schema:
1. Create `config_schema.json` based on your current config structure
2. Add descriptions for each property
3. Set appropriate defaults
4. Add validation constraints (min, max, etc.)
5. Reference the schema in your `manifest.json`
### Backward Compatibility
- Plugins without `config_schema.json` still work normally
- They simply won't have a configuration tab
- Users can still edit config via the Raw JSON editor
- The Configure button will navigate to a tab with a friendly message
## Future Enhancements
Potential improvements for future versions:
- **Advanced Schema Features**: Support for nested objects, conditional fields
- **Visual Validation**: Real-time validation feedback as user types
- **Color Pickers**: Special input for RGB/color array types
- **File Uploads**: Support for image/asset uploads
- **Import/Export**: Save and share plugin configurations
- **Presets**: Quick-switch between saved configurations
- **Documentation Links**: Link schema fields to plugin documentation
## Example Plugins
See these plugins for examples of config schemas:
- `hello-world`: Simple plugin with basic types
- `clock-simple`: Plugin with enum and number types
## Support
For questions or issues:
- Check the main LEDMatrix wiki
- Review plugin documentation
- Open an issue on GitHub
- Join the community Discord