mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-02 09:18:06 +00:00
fix(tools-tab): resolve remaining PR review comments
- api_v3: use getattr(api_v3, 'plugin_manager', None) instead of the module-level plugin_manager (always None); app.py sets the blueprint attribute, not the module global, so the fallback to plugin-repos was always taken - pages_v3: replace broad except Exception in _load_tools_partial with specific TemplateNotFound / OSError handlers and add [Pages V3][Tools] context prefix to log messages and error responses for easier Pi debugging - base.html: add Tools tab branch to the HTMX-unavailable fallback block in loadTabContent so the tab loads gracefully via direct fetch if HTMX never initialises Skipped: auth on execute_system_action — pre-existing app-wide design; reboot/shutdown and all other system actions share the same exposure. An app-level auth layer is the correct fix and is out of scope here. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
344f64ebba
commit
06ea4aa496
@@ -1666,7 +1666,8 @@ def execute_system_action():
|
||||
'output': _truncate_output(result.stdout, result.stderr)
|
||||
})
|
||||
elif action == 'install_plugin_requirements':
|
||||
plugins_dir = Path(plugin_manager.plugins_dir) if plugin_manager else PROJECT_ROOT / 'plugin-repos'
|
||||
active_pm = getattr(api_v3, 'plugin_manager', None)
|
||||
plugins_dir = Path(active_pm.plugins_dir) if active_pm else PROJECT_ROOT / 'plugin-repos'
|
||||
results = []
|
||||
if plugins_dir.exists():
|
||||
for p in sorted(plugins_dir.iterdir()):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from flask import Blueprint, render_template, flash
|
||||
from jinja2 import TemplateNotFound
|
||||
from markupsafe import escape
|
||||
import json
|
||||
import logging
|
||||
@@ -454,9 +455,12 @@ def _load_tools_partial():
|
||||
"""Load tools/utilities partial."""
|
||||
try:
|
||||
return render_template('v3/partials/tools.html')
|
||||
except Exception:
|
||||
logger.error("Error loading partial", exc_info=True)
|
||||
return "Error loading partial", 500
|
||||
except TemplateNotFound:
|
||||
logger.error("[Pages V3][Tools] Template not found: v3/partials/tools.html", exc_info=True)
|
||||
return "[Pages V3][Tools] Template is missing.", 500
|
||||
except OSError as exc:
|
||||
logger.error("[Pages V3][Tools] I/O error loading tools partial: %s", exc, exc_info=True)
|
||||
return "[Pages V3][Tools] Failed to load due to a file system error. Check logs.", 500
|
||||
|
||||
|
||||
def _load_plugin_config_partial(plugin_id):
|
||||
|
||||
@@ -1922,7 +1922,22 @@
|
||||
if (tab === 'overview' && typeof loadOverviewDirect === 'function') loadOverviewDirect();
|
||||
else if (tab === 'wifi' && typeof loadWifiDirect === 'function') loadWifiDirect();
|
||||
else if (tab === 'plugins' && typeof loadPluginsDirect === 'function') loadPluginsDirect();
|
||||
}
|
||||
else if (tab === 'tools') {
|
||||
fetch('/v3/partials/tools')
|
||||
.then(r => {
|
||||
if (!r.ok) throw new Error(r.status + ' ' + r.statusText);
|
||||
return r.text();
|
||||
})
|
||||
.then(html => {
|
||||
contentEl.innerHTML = html;
|
||||
contentEl.setAttribute('data-loaded', 'true');
|
||||
if (window.Alpine) window.Alpine.initTree(contentEl);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to load tools content:', err);
|
||||
contentEl.innerHTML = '<div class="bg-red-50 border border-red-200 rounded-lg p-4"><p class="text-red-800">Failed to load Tools. Please refresh the page.</p></div>';
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user