"feat: Refactor database connection and improve UI layout"

This commit is contained in:
Till Tomczak 2025-05-29 19:56:54 +02:00
parent bc72a88210
commit 2516ef08cc
5 changed files with 411 additions and 10 deletions

View File

@ -865,7 +865,7 @@ def user_update_settings():
contrast = "normal" contrast = "normal"
# Benutzer aus der Datenbank laden # Benutzer aus der Datenbank laden
user = db_session.query(User).filter(User.id == current_user.id).first() user = db_session.query(User).filter(User.id == int(current_user.id)).first()
if not user: if not user:
error = "Benutzer nicht gefunden." error = "Benutzer nicht gefunden."
@ -1016,7 +1016,7 @@ def user_change_password():
return redirect(url_for("user_profile")) return redirect(url_for("user_profile"))
db_session = get_db_session() db_session = get_db_session()
user = db_session.query(User).filter(User.id == current_user.id).first() user = db_session.query(User).filter(User.id == int(current_user.id)).first()
if user and user.check_password(current_password): if user and user.check_password(current_password):
# Passwort aktualisieren # Passwort aktualisieren
@ -1059,7 +1059,7 @@ def user_export_data():
"""Exportiert alle Benutzerdaten als JSON für DSGVO-Konformität""" """Exportiert alle Benutzerdaten als JSON für DSGVO-Konformität"""
try: try:
db_session = get_db_session() db_session = get_db_session()
user = db_session.query(User).filter(User.id == current_user.id).first() user = db_session.query(User).filter(User.id == int(current_user.id)).first()
if not user: if not user:
db_session.close() db_session.close()
@ -1109,7 +1109,7 @@ def user_update_profile_api():
data = request.get_json() data = request.get_json()
db_session = get_db_session() db_session = get_db_session()
user = db_session.query(User).filter(User.id == current_user.id).first() user = db_session.query(User).filter(User.id == int(current_user.id)).first()
if not user: if not user:
db_session.close() db_session.close()
@ -2430,7 +2430,7 @@ def get_current_job():
db_session = get_db_session() db_session = get_db_session()
try: try:
current_job = db_session.query(Job).filter( current_job = db_session.query(Job).filter(
Job.user_id == current_user.id, Job.user_id == int(current_user.id),
Job.status.in_(["scheduled", "running"]) Job.status.in_(["scheduled", "running"])
).order_by(Job.start_at).first() ).order_by(Job.start_at).first()
@ -2741,9 +2741,9 @@ def get_stats():
# Benutzer-spezifische Statistiken (falls nicht Admin) # Benutzer-spezifische Statistiken (falls nicht Admin)
user_stats = {} user_stats = {}
if not current_user.is_admin: if not current_user.is_admin:
user_jobs = db_session.query(Job).filter(Job.user_id == current_user.id).count() user_jobs = db_session.query(Job).filter(Job.user_id == int(current_user.id)).count()
user_completed = db_session.query(Job).filter( user_completed = db_session.query(Job).filter(
Job.user_id == current_user.id, Job.user_id == int(current_user.id),
Job.status == "completed" Job.status == "completed"
).count() ).count()
user_stats = { user_stats = {
@ -5039,7 +5039,7 @@ def perform_batch_operation():
else: else:
jobs = db_session.query(Job).filter( jobs = db_session.query(Job).filter(
Job.id.in_(job_ids), Job.id.in_(job_ids),
Job.user_id == current_user.id Job.user_id == int(current_user.id)
).all() ).all()
if not jobs: if not jobs:
@ -6148,4 +6148,4 @@ if __name__ == "__main__":
stop_queue_manager() stop_queue_manager()
except: except:
pass pass
sys.exit(1) sys.exit(1)

Binary file not shown.

Binary file not shown.

View File

@ -1 +1,401 @@
/**
* MYP Platform - UI Debug & Diagnostic Tool
* Diagnostiziert und behebt UI-Probleme in Echtzeit
*/
(function() {
'use strict';
console.log('🔍 UI-Debug-Tool wird geladen...');
// Debug-Konfiguration
const DEBUG_CONFIG = {
logClicks: true,
logErrors: true,
logNavigation: true,
showVisualFeedback: true,
autoFix: true
};
/**
* Hauptinitialisierung des Debug-Tools
*/
function initDebugTool() {
console.log('🚀 UI-Debug-Tool gestartet');
// 1. Click-Tracking
setupClickTracking();
// 2. Error-Tracking
setupErrorTracking();
// 3. Navigation-Tracking
setupNavigationTracking();
// 4. Element-Diagnostik
diagnoseElements();
// 5. Auto-Fix aktivieren
if (DEBUG_CONFIG.autoFix) {
setupAutoFix();
}
// 6. Debug-Panel erstellen
createDebugPanel();
console.log('✅ UI-Debug-Tool vollständig initialisiert');
}
/**
* Click-Tracking einrichten
*/
function setupClickTracking() {
if (!DEBUG_CONFIG.logClicks) return;
document.addEventListener('click', function(event) {
const target = event.target;
const info = {
element: target.tagName,
id: target.id || 'keine ID',
classes: target.className || 'keine Klassen',
href: target.href || 'kein href',
type: target.type || 'kein type',
dataAction: target.getAttribute('data-action') || 'keine data-action',
clickable: isElementClickable(target),
hasEventListeners: hasEventListeners(target)
};
console.log('👆 KLICK ERKANNT:', info);
// Visuelles Feedback
if (DEBUG_CONFIG.showVisualFeedback) {
showClickFeedback(target);
}
// Auto-Fix für nicht-klickbare Elemente
if (!info.clickable && DEBUG_CONFIG.autoFix) {
makeElementClickable(target);
}
}, true);
}
/**
* Error-Tracking einrichten
*/
function setupErrorTracking() {
if (!DEBUG_CONFIG.logErrors) return;
window.addEventListener('error', function(event) {
console.error('🚨 JAVASCRIPT-FEHLER:', {
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error
});
});
window.addEventListener('unhandledrejection', function(event) {
console.error('🚨 UNHANDLED PROMISE REJECTION:', event.reason);
});
}
/**
* Navigation-Tracking einrichten
*/
function setupNavigationTracking() {
if (!DEBUG_CONFIG.logNavigation) return;
// Link-Klicks verfolgen
document.addEventListener('click', function(event) {
const link = event.target.closest('a');
if (link) {
console.log('🔗 NAVIGATION:', {
href: link.href,
text: link.textContent.trim(),
target: link.target,
internal: isInternalLink(link.href)
});
}
});
}
/**
* Element-Diagnostik durchführen
*/
function diagnoseElements() {
console.log('🔍 Starte Element-Diagnostik...');
// Alle potentiell klickbaren Elemente finden
const clickableSelectors = [
'a', 'button', '[role="button"]', '[data-action]',
'.btn', '.clickable', '.nav-item', '.menu-item'
];
clickableSelectors.forEach(selector => {
const elements = document.querySelectorAll(selector);
console.log(`📊 ${selector}: ${elements.length} Elemente gefunden`);
elements.forEach((element, index) => {
const diagnosis = diagnoseElement(element);
if (diagnosis.issues.length > 0) {
console.warn(`⚠️ ${selector}[${index}] hat Probleme:`, diagnosis);
}
});
});
}
/**
* Einzelnes Element diagnostizieren
*/
function diagnoseElement(element) {
const issues = [];
const info = {
tag: element.tagName,
id: element.id,
classes: element.className,
href: element.href,
type: element.type,
disabled: element.disabled,
hidden: element.hidden || element.style.display === 'none',
hasEventListeners: hasEventListeners(element),
clickable: isElementClickable(element)
};
// Probleme identifizieren
if (element.tagName === 'A' && (!element.href || element.href === '#')) {
issues.push('Link ohne gültiges href-Attribut');
}
if (element.tagName === 'BUTTON' && element.disabled) {
issues.push('Button ist deaktiviert');
}
if (!info.hasEventListeners && !element.href && !element.onclick) {
issues.push('Keine Event-Listener oder onclick-Handler gefunden');
}
if (info.hidden) {
issues.push('Element ist versteckt');
}
return { info, issues };
}
/**
* Auto-Fix einrichten
*/
function setupAutoFix() {
console.log('🔧 Auto-Fix aktiviert');
// Alle problematischen Elemente finden und reparieren
const problematicElements = document.querySelectorAll('a[href="#"], button:disabled, [data-action]:not([onclick])');
problematicElements.forEach(element => {
fixElement(element);
});
// Mutation Observer für dynamisch hinzugefügte Elemente
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === Node.ELEMENT_NODE) {
const problematic = node.querySelectorAll('a[href="#"], button:disabled, [data-action]:not([onclick])');
problematic.forEach(fixElement);
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
}
/**
* Element reparieren
*/
function fixElement(element) {
console.log('🔧 Repariere Element:', element);
if (element.tagName === 'A' && (!element.href || element.href === '#')) {
// Link ohne href reparieren
element.style.cursor = 'pointer';
element.addEventListener('click', function(e) {
e.preventDefault();
console.log('🔗 Reparierter Link geklickt:', this);
});
}
if (element.tagName === 'BUTTON' && element.disabled) {
// Deaktivierten Button aktivieren (falls sicher)
if (!element.hasAttribute('data-keep-disabled')) {
element.disabled = false;
console.log('🔘 Button aktiviert:', element);
}
}
if (element.hasAttribute('data-action') && !hasEventListeners(element)) {
// Data-Action-Element ohne Event-Listener reparieren
element.addEventListener('click', function(e) {
e.preventDefault();
const action = this.getAttribute('data-action');
console.log('⚡ Data-Action ausgeführt:', action);
// Versuche globale Handler zu finden
if (window.MYP_UI_FIXES && window.MYP_UI_FIXES[action]) {
window.MYP_UI_FIXES[action]();
}
});
}
}
/**
* Debug-Panel erstellen
*/
function createDebugPanel() {
const panel = document.createElement('div');
panel.id = 'debug-panel';
panel.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
width: 300px;
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 10px;
border-radius: 5px;
font-family: monospace;
font-size: 12px;
z-index: 10000;
max-height: 400px;
overflow-y: auto;
display: none;
`;
panel.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<strong>🔍 UI Debug Panel</strong>
<button onclick="this.parentElement.parentElement.style.display='none'" style="background: red; color: white; border: none; padding: 2px 6px; border-radius: 3px; cursor: pointer;">×</button>
</div>
<div id="debug-content">
<div> Debug-Tool aktiv</div>
<div>👆 Klicks werden verfolgt</div>
<div>🔧 Auto-Fix aktiviert</div>
</div>
`;
document.body.appendChild(panel);
// Toggle-Button für Debug-Panel
const toggleButton = document.createElement('button');
toggleButton.textContent = '🔍';
toggleButton.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
border-radius: 50%;
background: #007bff;
color: white;
border: none;
font-size: 20px;
cursor: pointer;
z-index: 10001;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
`;
toggleButton.addEventListener('click', function() {
const panel = document.getElementById('debug-panel');
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
});
document.body.appendChild(toggleButton);
}
/**
* Hilfsfunktionen
*/
function isElementClickable(element) {
const style = window.getComputedStyle(element);
return style.pointerEvents !== 'none' &&
style.display !== 'none' &&
style.visibility !== 'hidden' &&
!element.disabled;
}
function hasEventListeners(element) {
// Vereinfachte Prüfung - in der Realität schwer zu detektieren
return element.onclick !== null ||
element.getAttribute('onclick') !== null ||
element.hasAttribute('data-action');
}
function isInternalLink(href) {
if (!href) return false;
return href.startsWith('/') ||
href.startsWith('./') ||
href.startsWith('../') ||
href.includes(window.location.hostname);
}
function makeElementClickable(element) {
if (!isElementClickable(element)) {
element.style.cursor = 'pointer';
element.style.pointerEvents = 'auto';
if (!hasEventListeners(element)) {
element.addEventListener('click', function(e) {
console.log('🔧 Auto-Fix Klick auf:', this);
});
}
}
}
function showClickFeedback(element) {
const feedback = document.createElement('div');
feedback.style.cssText = `
position: absolute;
background: rgba(0, 255, 0, 0.3);
border: 2px solid #00ff00;
pointer-events: none;
z-index: 9999;
border-radius: 3px;
`;
const rect = element.getBoundingClientRect();
feedback.style.left = rect.left + 'px';
feedback.style.top = rect.top + 'px';
feedback.style.width = rect.width + 'px';
feedback.style.height = rect.height + 'px';
document.body.appendChild(feedback);
setTimeout(() => {
feedback.remove();
}, 500);
}
/**
* Initialisierung
*/
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initDebugTool);
} else {
initDebugTool();
}
// Globale Debug-Funktionen
window.DEBUG_UI = {
diagnose: diagnoseElements,
fix: setupAutoFix,
toggle: function() {
const panel = document.getElementById('debug-panel');
if (panel) {
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
}
}
};
console.log('✅ UI-Debug-Tool geladen');
})();

View File

@ -577,6 +577,7 @@
<!-- JavaScript --> <!-- JavaScript -->
<script src="{{ url_for('static', filename='js/fix-ui-issues.js') }}"></script> <script src="{{ url_for('static', filename='js/fix-ui-issues.js') }}"></script>
<script src="{{ url_for('static', filename='js/debug-ui.js') }}"></script>
<script src="{{ url_for('static', filename='js/ui-components.js') }}"></script> <script src="{{ url_for('static', filename='js/ui-components.js') }}"></script>
<script src="{{ url_for('static', filename='js/dark-mode-fix.js') }}"></script> <script src="{{ url_for('static', filename='js/dark-mode-fix.js') }}"></script>
<script src="{{ url_for('static', filename='js/optimization-features.js') }}"></script> <script src="{{ url_for('static', filename='js/optimization-features.js') }}"></script>