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:
Chuck
2026-09-28 08:26:27 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 7eb7a58d0c
commit 76f5d8a336
11 changed files with 103 additions and 697 deletions
+7 -7
View File
@@ -85,7 +85,7 @@
html += `
<div class="flex justify-center mb-2">
<span id="${fieldId}_value" class="text-lg font-semibold text-gray-700">
${escapeHtml(prefix)}${currentValue}${escapeHtml(suffix)}
${escapeHtml(prefix)}${escapeHtml(currentValue)}${escapeHtml(suffix)}
</span>
</div>
`;
@@ -96,10 +96,10 @@
<input type="range"
id="${fieldId}_input"
name="${escapeHtml(options.name || fieldId)}"
value="${currentValue}"
min="${min}"
max="${max}"
step="${step}"
value="${escapeAttr(currentValue)}"
min="${escapeAttr(min)}"
max="${escapeAttr(max)}"
step="${escapeAttr(step)}"
${disabled ? 'disabled' : ''}
oninput="window.LEDMatrixWidgets.getHandlers('slider').onInput('${fieldId}')"
onchange="window.LEDMatrixWidgets.getHandlers('slider').onChange('${fieldId}')"
@@ -110,8 +110,8 @@
if (showMinMax) {
html += `
<div class="flex justify-between mt-1">
<span class="text-xs text-gray-400">${escapeHtml(prefix)}${min}${escapeHtml(suffix)}</span>
<span class="text-xs text-gray-400">${escapeHtml(prefix)}${max}${escapeHtml(suffix)}</span>
<span class="text-xs text-gray-400">${escapeHtml(prefix)}${escapeHtml(min)}${escapeHtml(suffix)}</span>
<span class="text-xs text-gray-400">${escapeHtml(prefix)}${escapeHtml(max)}${escapeHtml(suffix)}</span>
</div>
`;
}