mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
* fix(ui): wrap plugin tabs to new lines instead of scrolling Change plugin tabs row from overflow-x-auto to flex-wrap so that when many plugins are installed, tabs break to new lines instead of becoming smaller or requiring horizontal scrolling. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): use gap-x instead of space-x for proper wrapped row alignment Switch from space-x-* to gap-x-* utilities so wrapped rows align correctly without indentation on subsequent lines. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): add missing flex-wrap and gap utilities to CSS The project uses hand-written Tailwind-like CSS, not actual Tailwind. Added missing utility classes needed for plugin tabs wrapping: - flex-wrap - gap-x-4, gap-x-6, gap-x-8, gap-y-2 - lg:gap-x-6, xl:gap-x-8 responsive variants Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): apply flex-wrap to system tabs row Apply the same wrapping behavior to the system tabs row (Overview, General, WiFi, etc.) so they also wrap to new lines on smaller viewports instead of scrolling. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): constrain tab container width to enable flex-wrap Add max-w-full and overflow-hidden to tab row containers to properly constrain their width, allowing flex-wrap to work correctly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): remove overflow-hidden that was hiding tabs Revert the max-w-full overflow-hidden approach as it was hiding content. Keep both rows using flex-wrap with gap utilities. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: Add custom-leagues widget support for soccer plugin - Add server-side template rendering for x-widget="custom-leagues" - Renders table with Name, League Code, Priority, Enabled columns - Includes inline JavaScript for add/remove row functionality - Uses indexed field naming for proper array serialization - Shows common ESPN league codes as hint This enables the soccer scoreboard plugin's custom leagues feature to work properly in the web UI. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): reduce tab gap spacing for tighter layout Reduce horizontal gap between tabs from gap-x-4/6/8 to gap-x-2/3/4 for a more compact appearance. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(widget): Replace custom-leagues with generic array-table widget - Add generic array-table widget that reads columns from schema - Support x-columns to specify which columns to display - Auto-detect columns from items.properties if x-columns not specified - Remove hardcoded custom-leagues implementation - Any plugin can now use x-widget: "array-table" for array-of-objects Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): use data attributes for array table button to avoid JSON escaping issues Move JSON blobs (item_properties and display_columns) from inline onclick to data-* attributes with proper HTML entity escaping via Jinja's |e filter. Update addArrayTableRow() to read and parse these data attributes. This fixes HTML attribute breakage caused by tojson emitting double quotes inside the onclick attribute value. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): update Add button state when array table rows change Add updateAddButtonState() helper that toggles the Add button's disabled attribute and opacity based on current row count vs maxItems. Called after addArrayTableRow() and removeArrayTableRow(), and also on page load to ensure correct initial state. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): add try/catch for JSON parsing in addArrayTableRow Wrap JSON.parse calls for data-item-properties and data-display-columns in try/catch blocks with fallback to {} and [] respectively. Logs error with raw attribute values to help debug malformed JSON. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(array-table): Fix getValue input name validation and setValue Add button state sync - Fix getValue to use early-continue guard preventing errors on inputs without names - Add updateAddButtonState call in setValue to refresh Add button state after repopulating rows * fix(ui): make Configure button larger than Uninstall in plugin manager Swapped button sizes in installed plugins section - Configure button is now the largest (flex-2), Update is medium (flex-1), and Uninstall is smallest (no flex class). This prioritizes the Configure action over Uninstall. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ui): correct forEach continue and plugin button flex sizing - Replace invalid continue with return in array-table forEach callback - Remove redundant hidden input type check in array-table getValue - Fix plugin button sizing using inline flex styles instead of invalid flex-2 class - Configure button now properly sized at flex: 2, Update and Uninstall at flex: 1 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor(ui): reorganize plugin buttons into two-row layout Configure button now takes full width on first row, while Update and Uninstall buttons share the second row evenly. This makes Configure more prominent and separates destructive actions to a second row. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ui): override inline-flex on Configure button to enable full width The .btn class uses display: inline-flex which prevents w-full from working. Added inline style to override with display: flex and width: 100% so the Configure button properly takes the full width of its row. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ui): use inline styles for plugin action buttons layout Replace Tailwind classes with explicit inline styles to ensure proper two-row layout for plugin action buttons. Configure button on first row at full width, Update and Uninstall sharing second row evenly. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
LED Matrix Web Interface V3
Modern, production web interface for controlling the LED Matrix display.
Overview
This directory contains the active V3 web interface with the following features:
- Real-time display preview via Server-Sent Events (SSE)
- Plugin management and configuration
- System monitoring and logs
- Modern, responsive UI
- RESTful API
Directory Structure
web_interface/
├── app.py # Main Flask application
├── start.py # Startup script
├── run.sh # Shell runner script
├── requirements.txt # Python dependencies
├── blueprints/ # Flask blueprints
│ ├── api_v3.py # API endpoints
│ └── pages_v3.py # Page routes
├── templates/ # HTML templates
│ └── v3/
│ ├── base.html
│ ├── index.html
│ └── partials/
└── static/ # CSS/JS assets
└── v3/
├── app.css
└── app.js
Running the Web Interface
Standalone (Development)
From the project root:
python3 web_interface/start.py
Or using the shell script:
./web_interface/run.sh
As a Service (Production)
The web interface can run as a systemd service that starts automatically based on the web_display_autostart configuration setting:
sudo systemctl start ledmatrix-web
sudo systemctl enable ledmatrix-web # Start on boot
Accessing the Interface
Once running, access the web interface at:
- Local: http://localhost:5000
- Network: http://:5000
Configuration
The web interface reads configuration from:
config/config.json- Main configurationconfig/secrets.json- API keys and secrets
API Documentation
The V3 API is available at /api/v3/ with the following endpoints:
Configuration
GET /api/v3/config/main- Get main configurationPOST /api/v3/config/main- Save main configurationGET /api/v3/config/secrets- Get secrets configurationPOST /api/v3/config/secrets- Save secrets configuration
Display Control
POST /api/v3/display/start- Start display servicePOST /api/v3/display/stop- Stop display servicePOST /api/v3/display/restart- Restart display serviceGET /api/v3/display/status- Get display service status
Plugins
GET /api/v3/plugins- List installed pluginsGET /api/v3/plugins/<id>- Get plugin detailsPOST /api/v3/plugins/<id>/config- Update plugin configurationGET /api/v3/plugins/<id>/enable- Enable pluginGET /api/v3/plugins/<id>/disable- Disable plugin
Plugin Store
GET /api/v3/store/plugins- List available pluginsPOST /api/v3/store/install/<id>- Install pluginPOST /api/v3/store/uninstall/<id>- Uninstall pluginPOST /api/v3/store/update/<id>- Update plugin
Real-time Streams (SSE)
GET /api/v3/stream/stats- System statistics streamGET /api/v3/stream/display- Display preview streamGET /api/v3/stream/logs- Service logs stream
Development
When making changes to the web interface:
- Edit files in this directory
- Test changes by running
python3 web_interface/start.py - Restart the service if running:
sudo systemctl restart ledmatrix-web
Notes
- Templates and static files use the
v3/prefix to allow for future versions - The interface uses Flask blueprints for modular organization
- SSE streams provide real-time updates without polling