🐛 Update: Added support for the 'find' command in settings.local.json. Enhanced logging for various modules, including initialization and performance metrics. Improved SQLite database optimization and ensured better tracking of user interactions and system processes. 📚

This commit is contained in:
2025-06-14 16:26:43 +02:00
parent ee54bc273c
commit 89037861e3
2472 changed files with 691099 additions and 1 deletions

View File

@@ -0,0 +1,471 @@
/**
* MYP Professional Network Diagram - Interactive Script
* Mercedes-Benz 3D-Druck-Management-System
*/
class MYPNetworkDiagram {
constructor() {
this.nodes = document.querySelectorAll('.node');
this.connections = document.querySelectorAll('.connection');
this.isInteractive = true;
this.init();
}
init() {
this.setupNodeInteractions();
this.setupConnectionHighlighting();
this.logSystemInfo();
// Add keyboard shortcuts
this.setupKeyboardControls();
}
/**
* Setup interactive node behaviors
*/
setupNodeInteractions() {
this.nodes.forEach(node => {
// Mouse enter - highlight connections
node.addEventListener('mouseenter', (e) => {
if (!this.isInteractive) return;
this.highlightNodeConnections(e.target);
});
// Mouse leave - reset highlights
node.addEventListener('mouseleave', () => {
if (!this.isInteractive) return;
this.resetHighlights();
});
// Click - show node details
node.addEventListener('click', (e) => {
this.showNodeDetails(e.target);
});
// Make nodes keyboard accessible
node.setAttribute('tabindex', '0');
node.setAttribute('role', 'button');
});
}
/**
* Highlight connections related to the active node
*/
highlightNodeConnections(activeNode) {
const nodeId = activeNode.id;
const nodeType = this.getNodeType(activeNode);
// Get connected node IDs
const connections = this.getNodeConnections(nodeId, nodeType);
// Dim all nodes first
this.nodes.forEach(node => {
if (node !== activeNode && !connections.includes(node.id)) {
node.style.opacity = '0.3';
node.style.filter = 'blur(1px)';
}
});
// Highlight connected nodes
connections.forEach(connectedId => {
const connectedNode = document.getElementById(connectedId);
if (connectedNode) {
connectedNode.style.opacity = '1';
connectedNode.style.filter = 'none';
connectedNode.style.transform = 'translateY(-4px) scale(1.02)';
}
});
// Highlight relevant connections
this.highlightConnections(nodeId, connections);
}
/**
* Reset all visual highlights
*/
resetHighlights() {
this.nodes.forEach(node => {
node.style.opacity = '';
node.style.filter = '';
node.style.transform = '';
});
this.connections.forEach(conn => {
conn.style.opacity = '';
conn.style.strokeWidth = '';
});
}
/**
* Highlight specific connections
*/
highlightConnections(nodeId, connectedIds) {
this.connections.forEach(conn => {
conn.style.opacity = '0.2';
});
// This would need more sophisticated logic to match
// connections to specific nodes based on coordinates
// For now, we'll use a simplified approach
}
/**
* Get node type from CSS classes
*/
getNodeType(node) {
if (node.classList.contains('frontend-node')) return 'frontend';
if (node.classList.contains('backend-node')) return 'backend';
if (node.classList.contains('smartplug-node')) return 'smartplug';
if (node.classList.contains('printer-node')) return 'printer';
return 'unknown';
}
/**
* Get connected node IDs for a given node
*/
getNodeConnections(nodeId, nodeType) {
const connectionMap = {
// Frontend connections
'kiosk': ['webapp', 'server'],
'webapp': ['kiosk', 'auth', 'flask'],
'auth': ['webapp', 'security'],
// Backend connections
'server': ['kiosk', 'flask'],
'flask': ['webapp', 'server', 'database'],
'database': ['flask', 'scheduler'],
'scheduler': ['database', 'security', 'plug1', 'plug2', 'plug3', 'plug4', 'plug6'],
'security': ['auth', 'scheduler', 'monitor'],
'monitor': ['security', 'plug6', 'printer5'],
// Smart plug connections
'plug1': ['scheduler', 'printer1'],
'plug2': ['scheduler', 'printer2'],
'plug3': ['scheduler', 'printer3'],
'plug4': ['scheduler', 'printer4'],
'plug6': ['scheduler', 'printer5', 'monitor'],
// Printer connections
'printer1': ['plug1'],
'printer2': ['plug2'],
'printer3': ['plug3'],
'printer4': ['plug4'],
'printer5': ['plug6', 'monitor']
};
return connectionMap[nodeId] || [];
}
/**
* Show detailed information about a node
*/
showNodeDetails(node) {
const nodeLabel = node.querySelector('.node-label').textContent;
const nodeDetail = node.querySelector('.node-detail').textContent;
const nodeType = this.getNodeType(node);
const details = this.getNodeDetailedInfo(node.id, nodeType);
console.log(`🔧 MYP Node: ${nodeLabel}`);
console.log(`📋 Details: ${nodeDetail}`);
console.log(`🔗 Type: ${nodeType}`);
console.log(`📊 Info:`, details);
// Visual feedback
node.style.transform = 'scale(0.95)';
setTimeout(() => {
node.style.transform = '';
}, 150);
// Could show a modal or tooltip here
this.showTooltip(node, details);
}
/**
* Get detailed information for a node
*/
getNodeDetailedInfo(nodeId, nodeType) {
const detailsMap = {
'kiosk': {
description: 'Mercedes-Benz Kiosk Terminal im TBA Marienfelde',
specs: ['Touch-Interface', 'HTTPS-only', 'Corporate Design'],
status: 'Online'
},
'webapp': {
description: 'Next.js Progressive Web App mit Flask Backend',
specs: ['React/Next.js', 'PWA Features', 'Responsive Design'],
status: 'Active'
},
'auth': {
description: 'Authentifizierungssystem mit bcrypt und OTP',
specs: ['bcrypt Hashing', 'OTP Guest Access', 'Session Management'],
status: 'Secure'
},
'server': {
description: 'Raspberry Pi 4B Production Server',
specs: ['ARM Cortex-A72', '8GB RAM', 'Debian OS'],
status: 'Online - 192.168.0.100'
},
'flask': {
description: 'Flask Backend mit 15+ Blueprint Modulen',
specs: ['Python Flask', 'SQLAlchemy ORM', 'REST API'],
status: 'Running'
},
'database': {
description: 'SQLite WAL Database mit Thread-Pool',
specs: ['WAL Mode', 'Thread-Safe', 'Auto-Backup'],
status: 'Synchronized'
},
'scheduler': {
description: 'APScheduler Job Queue System',
specs: ['Background Jobs', 'Cron Tasks', 'Queue Management'],
status: 'Active'
},
'security': {
description: 'Security Suite mit SSL/TLS Management',
specs: ['SSL/TLS', 'Audit Logging', 'CSRF Protection'],
status: 'Protected'
},
'monitor': {
description: 'System Monitoring & Analytics',
specs: ['Performance Tracking', 'Error Logging', 'Health Checks'],
status: 'Monitoring'
}
};
// Smart Plugs
if (nodeId.startsWith('plug')) {
const plugNumber = nodeId.replace('plug', '');
return {
description: `TP-Link Tapo P110 Smart Plug #${plugNumber}`,
specs: ['Energy Monitoring', '230V AC Control', 'Remote Management'],
status: `Online - 192.168.0.10${plugNumber}`
};
}
// Printers
if (nodeId.startsWith('printer')) {
const printerNumber = nodeId.replace('printer', '');
const printerModels = {
'1': 'Prusa MK3S+',
'2': 'Ender 3 Pro',
'3': 'Bambu Lab A1',
'4': 'Prusa MINI+',
'5': 'Artillery X1'
};
return {
description: `3D-Drucker Arbeitsplatz ${printerNumber}`,
specs: [printerModels[printerNumber], 'Smart-Plug Controlled', 'Job Queue Ready'],
status: 'Ready for Production'
};
}
return detailsMap[nodeId] || {
description: 'MYP System Component',
specs: ['Network Connected', 'Monitored'],
status: 'Online'
};
}
/**
* Show tooltip with node information
*/
showTooltip(node, details) {
// Remove existing tooltip
const existingTooltip = document.querySelector('.node-tooltip');
if (existingTooltip) {
existingTooltip.remove();
}
const tooltip = document.createElement('div');
tooltip.className = 'node-tooltip';
tooltip.innerHTML = `
<div class="tooltip-header">${details.description}</div>
<div class="tooltip-specs">
${details.specs.map(spec => `<div class="tooltip-spec">• ${spec}</div>`).join('')}
</div>
<div class="tooltip-status">Status: ${details.status}</div>
`;
// Style the tooltip
tooltip.style.cssText = `
position: absolute;
background: rgba(0, 0, 0, 0.95);
color: white;
padding: 12px;
border-radius: 8px;
font-size: 0.8rem;
max-width: 250px;
z-index: 1000;
pointer-events: none;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
`;
// Position tooltip
const rect = node.getBoundingClientRect();
tooltip.style.left = (rect.left + rect.width + 10) + 'px';
tooltip.style.top = rect.top + 'px';
document.body.appendChild(tooltip);
// Auto-remove after 3 seconds
setTimeout(() => {
tooltip.remove();
}, 3000);
}
/**
* Setup connection highlighting on hover
*/
setupConnectionHighlighting() {
this.connections.forEach(conn => {
conn.addEventListener('mouseenter', () => {
if (!this.isInteractive) return;
conn.style.strokeWidth = '4';
conn.style.opacity = '1';
});
conn.addEventListener('mouseleave', () => {
if (!this.isInteractive) return;
conn.style.strokeWidth = '';
conn.style.opacity = '';
});
});
}
/**
* Setup keyboard controls
*/
setupKeyboardControls() {
document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'Escape':
this.resetHighlights();
break;
case 'i':
case 'I':
this.toggleInteractivity();
break;
case 'r':
case 'R':
this.resetDiagram();
break;
}
});
}
/**
* Toggle interactivity mode
*/
toggleInteractivity() {
this.isInteractive = !this.isInteractive;
console.log(`🎮 Interactivity ${this.isInteractive ? 'enabled' : 'disabled'}`);
if (!this.isInteractive) {
this.resetHighlights();
}
}
/**
* Reset diagram to initial state
*/
resetDiagram() {
this.resetHighlights();
// Remove any tooltips
document.querySelectorAll('.node-tooltip').forEach(tooltip => {
tooltip.remove();
});
console.log('🔄 Diagram reset');
}
/**
* Log system information
*/
logSystemInfo() {
console.log('🚀 MYP Professional Network Diagram loaded');
console.log('📊 System Components:', this.nodes.length);
console.log('🔗 Connections:', this.connections.length);
console.log('🏭 Location: Mercedes-Benz TBA Marienfelde');
console.log('🖥️ Server: Raspberry Pi 4B (192.168.0.100)');
console.log('🔌 Smart Plugs: 5x Tapo P110 (192.168.0.101-104, 106)');
console.log('🖨️ 3D Printers: 5 Arbeitsplätze');
console.log('⌨️ Keyboard: [I] Toggle Interactivity, [R] Reset, [ESC] Clear');
}
}
/**
* Utility class for diagram export and screenshot optimization
*/
class DiagramExport {
static enableScreenshotMode() {
document.body.classList.add('screenshot-mode');
const style = document.createElement('style');
style.id = 'screenshot-styles';
style.textContent = `
.screenshot-mode .node {
animation: none !important;
}
.screenshot-mode .node:hover {
transform: none !important;
box-shadow: inherit !important;
}
.screenshot-mode .connection {
animation: none !important;
}
`;
document.head.appendChild(style);
console.log('📸 Screenshot mode enabled');
}
static disableScreenshotMode() {
document.body.classList.remove('screenshot-mode');
const screenshotStyles = document.getElementById('screenshot-styles');
if (screenshotStyles) {
screenshotStyles.remove();
}
console.log('🎮 Interactive mode restored');
}
static printDiagram() {
window.print();
}
}
/**
* Initialize when DOM is ready
*/
document.addEventListener('DOMContentLoaded', () => {
// Initialize the network diagram
const networkDiagram = new MYPNetworkDiagram();
// Make utilities globally available
window.MYP = {
diagram: networkDiagram,
export: DiagramExport
};
// Check URL parameters for special modes
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('screenshot') === 'true') {
DiagramExport.enableScreenshotMode();
}
if (urlParams.get('print') === 'true') {
setTimeout(() => {
DiagramExport.printDiagram();
}, 1000);
}
console.log('✅ MYP Professional Network Diagram initialized');
console.log('🔧 Access via: window.MYP.diagram');
console.log('📸 Screenshot mode: ?screenshot=true');
});