mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-05-27 06:23:33 +00:00
feat(ui): add reusable json-file-manager widget (#352)
* feat(ui): add reusable json-file-manager widget for plugin file management Introduces JsonFileManager — a zero-CDN, keyboard-accessible, configurable widget for managing JSON data files from plugin configuration forms. web_interface/static/v3/js/widgets/json-file-manager.js (new): - Self-contained class with scoped CSS (no global leakage) - File list with cards: enable/disable toggle, entry count, size, date - Drag-and-drop + click-to-browse JSON upload - Textarea-based JSON editor (no CDN); Format + Validate buttons - Ctrl+S to save, Escape to close any open modal - Create-new-file modal with configurable fields and validation - Delete confirmation modal - All actions (list/get/save/upload/delete/create/toggle) are configurable via x-widget-config in config_schema.json — no plugin-ID hardcoding web_interface/static/v3/plugins_manager.js: - New handler for x-widget: "json-file-manager" — renders mount div, instantiates JsonFileManager with x-widget-config and plugin ID web_interface/templates/v3/base.html: - Include json-file-manager.js (defer) before plugins_manager.js Usage: set x-widget: "json-file-manager" + x-widget-config in any plugin's config_schema.json (see ledmatrix-plugins of-the-day for a complete example). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(json-file-manager): review fixes — type=button, finally, display_name, instance tracking - Add type="button" to every button in the template (replace_all) so none default to submit inside the plugin-config-form - Wrap _doSave/_doDelete/_doCreate fetch blocks in try/finally so _idle() always fires, not only on the error path - _doCreate validation: skip the required-check for display_name (f.key !== 'display_name') and only validate pattern when val is non-empty, so the auto-derive logic at the end of the loop can run; simplify the derive block to a single conditional instead of nested DOM lookups - plugins_manager.js: track instances in window.__jfmInstances[safeFieldId] and call _destroy() on any previous instance before mounting a new one, preventing duplicate keydown handlers when the config form is re-rendered Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(json-file-manager): use validity.patternMismatch; destroy all instances on remount - Replace `new RegExp(f.pattern).test(val)` with `el.validity.patternMismatch` to avoid potential SyntaxError from untrusted pattern strings and rely on the browser's already-validated pattern attribute instead - plugins_manager.js: iterate all window.__jfmInstances and call _destroy() on every entry before mounting, then reset the map, so no orphaned keydown handlers survive when any plugin config form is re-rendered Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(plugins_manager): scope jfm instance teardown to current mount key only The global sweep (Object.values + window.__jfmInstances = {}) destroyed sibling file-manager widgets when any one of them was remounted. Replace with a targeted destroy of window.__jfmInstances[safeFieldId] only, leaving all other entries untouched. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(json-file-manager): address Codacy security warnings - Replace Math.random() with crypto.getRandomValues() for UID generation - Remove unused variable `u` in _card() - Guard this.actions property access with hasOwnProperty - Replace btn.innerHTML in _busy/_idle with DOM manipulation + textContent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4625,6 +4625,9 @@
|
||||
<script src="{{ url_for('static', filename='v3/js/widgets/timezone-selector.js') }}" defer></script>
|
||||
<script src="{{ url_for('static', filename='v3/js/widgets/plugin-loader.js') }}" defer></script>
|
||||
|
||||
<!-- Reusable JSON file manager widget (used by of-the-day and others via x-widget: json-file-manager) -->
|
||||
<script src="{{ url_for('static', filename='v3/js/widgets/json-file-manager.js') }}" defer></script>
|
||||
|
||||
<!-- Legacy plugins_manager.js (for backward compatibility during migration) -->
|
||||
<script src="{{ url_for('static', filename='v3/plugins_manager.js') }}?v=20260307" defer></script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user