mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-05 14:55:08 +00:00
fix(web): seven web UI bugs, and remove dead plugins_manager.js helpers (#647)
- Operation History: the plugin filter lists the installed plugin ids
instead of one option, "plugins" (Object.keys of {plugins: [...]}).
- Ctrl/Cmd+S submits the active tab's first visible form with
requestSubmit() (validation and onsubmit guards run) instead of a bare
Event on the first form in the document; skipped inside a modal dialog
and on tabs without a form.
- Overview "Check Updates" confirms like "Update Code", takes its button
explicitly (no implicit global event) and shows the server's message.
Both, and the Tools tab git pull, raise the restart-pending banner on
restart_required.
- Tools: toolsAction and diagnostics show the server's error message;
only a non-JSON body falls back to HTTP <status>.
- Installed list after uninstall: PluginAPI writes clear the throttler's
GET cache, a forced loadInstalledPlugins clears it too, and the
post-uninstall reload goes through refreshInstalledPlugins().
- Plugin widgets load from /static/plugin-widgets/ only (the other two
paths have no route).
- Raw JSON editor escapes the parse error; slider escapes value/min/max/step.
- Removed the unreferenced array-of-objects and key-value helpers from
plugins_manager.js, the textarea auto-resize and Ctrl+R handlers in
app.js, and a redundant ?v= on the plugins_manager.js script tag.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -229,31 +229,32 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// SSE streams (and window.reconnectSSE) are owned by window.LEDStreams in
|
||||
// js/app-shell.js — do not open EventSources for stats/display here.
|
||||
|
||||
// Auto-resize textareas
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const textareas = document.querySelectorAll('textarea');
|
||||
textareas.forEach(textarea => {
|
||||
textarea.addEventListener('input', function() {
|
||||
this.style.height = 'auto';
|
||||
this.style.height = this.scrollHeight + 'px';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', function(e) {
|
||||
// Ctrl/Cmd + R to refresh
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'r') {
|
||||
e.preventDefault();
|
||||
location.reload();
|
||||
}
|
||||
|
||||
// Ctrl/Cmd + S to save current form
|
||||
// Ctrl/Cmd + S to save the form on the active tab: the first visible form
|
||||
// in that tab's panel (#<tab>-content, or #plugin-config-<id> for a plugin
|
||||
// tab). The panel is looked up by activeTab rather than by visibility
|
||||
// alone because during the x-transition between tabs both are visible.
|
||||
// requestSubmit() runs validation and onsubmit guards like a real submit;
|
||||
// with no visible form, do nothing. Inside a modal dialog the shortcut is
|
||||
// the dialog's (json-file-manager saves its file on Ctrl+S), so the tab's
|
||||
// form is left alone.
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
|
||||
e.preventDefault();
|
||||
const form = document.querySelector('form');
|
||||
if (form) {
|
||||
form.dispatchEvent(new Event('submit'));
|
||||
const active = document.activeElement;
|
||||
if (active && active.closest && active.closest('[aria-modal="true"]')) {
|
||||
return;
|
||||
}
|
||||
const app = typeof window.getApp === 'function' ? window.getApp() : null;
|
||||
const tab = app && app.activeTab;
|
||||
const panel = (tab && (document.getElementById(tab + '-content') ||
|
||||
document.getElementById('plugin-config-' + tab))) ||
|
||||
document.getElementById('tab-content');
|
||||
if (!panel) return;
|
||||
const form = Array.from(panel.querySelectorAll('form'))
|
||||
.find(f => f.getClientRects().length > 0);
|
||||
if (form && typeof form.requestSubmit === 'function') {
|
||||
form.requestSubmit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user