Fehler beseitigt in der Anzeige

This commit is contained in:
Eduard Wisch 2026-02-11 17:38:29 +01:00
parent 10dbf420c3
commit 49087bf8f6
2 changed files with 235 additions and 36 deletions

View file

@ -1652,7 +1652,12 @@
/* Rails (Hutschienen) */
.schematic-rail {
cursor: default !important;
cursor: pointer !important;
transition: filter 0.2s ease !important;
}
.schematic-rail:hover {
filter: brightness(1.3) !important;
}
.schematic-rail-bg {

View file

@ -4465,7 +4465,10 @@
},
init: function(anlageId) {
if (!anlageId) return;
if (!anlageId) {
console.error('SchematicEditor.init: No anlageId provided!');
return;
}
this.anlageId = anlageId;
this.bindEvents();
this.loadData();
@ -4528,7 +4531,7 @@
// Hide popups when clicking elsewhere
$(document).off('mousedown.hidePopup').on('mousedown.hidePopup', function(e) {
// Don't hide if clicking on popup buttons
if ($(e.target).closest('.schematic-connection-popup, .schematic-equipment-popup').length) {
if ($(e.target).closest('.schematic-connection-popup, .schematic-equipment-popup, .schematic-carrier-popup').length) {
return;
}
// Don't hide if clicking on SVG elements (handlers will handle it)
@ -4537,6 +4540,7 @@
}
self.hideConnectionPopup();
self.hideEquipmentPopup();
self.hideCarrierPopup();
});
// Clear all connections
@ -4584,12 +4588,14 @@
self.showBusbarPopup(connectionId, e.clientX, e.clientY);
});
// Hutschiene (rail) click - show edit popup
// Rail (Hutschiene) click - show popup for editing
$(document).off('click.rail').on('click.rail', '.schematic-rail', function(e) {
e.preventDefault();
e.stopPropagation();
var carrierId = $(this).data('carrier-id');
self.showCarrierPopup(carrierId, e.clientX, e.clientY);
if (carrierId) {
self.showCarrierPopup(carrierId, e.clientX, e.clientY);
}
});
// Terminal right-click - show output/cable dialog
@ -4989,11 +4995,9 @@
// Prevent multiple simultaneous loads (race condition fix)
if (this.isLoading) {
console.log('SchematicEditor loadData: Already loading, skipping...');
return;
}
this.isLoading = true;
console.log('SchematicEditor loadData: Starting...');
// Load panels with carriers for this anlage
$.ajax({
@ -5003,7 +5007,6 @@
success: function(response) {
if (response.success) {
self.panels = response.panels || [];
console.log('SchematicEditor loadData: Loaded ' + self.panels.length + ' panels');
// Flatten carriers from all panels
self.carriers = [];
self.panels.forEach(function(panel) {
@ -5014,16 +5017,15 @@
});
}
});
console.log('SchematicEditor loadData: Loaded ' + self.carriers.length + ' carriers');
self.loadEquipment();
} else {
console.error('SchematicEditor loadData: Failed to load panels', response);
self.isLoading = false;
}
},
error: function(xhr, status, error) {
console.error('SchematicEditor loadData: AJAX error', error);
self.isLoading = false;
// Show visible error
$('.schematic-editor-canvas').html('<div style="padding:20px;color:#e74c3c;">AJAX Fehler beim Laden: ' + error + '</div>');
}
});
},
@ -5054,7 +5056,6 @@
$.when.apply($, promises).then(function() {
self.loadConnections();
}).fail(function() {
console.error('SchematicEditor loadEquipment: One or more AJAX requests failed');
self.isLoading = false;
});
},
@ -5079,10 +5080,6 @@
});
}
console.log('SchematicEditor: Loaded ' + self.connections.length + ' connections', self.connections);
console.log('SchematicEditor: Equipment count: ' + self.equipment.length, self.equipment);
} else {
console.error('SchematicEditor: Failed to load connections', response);
}
// Initialize canvas now that all data is loaded
if (!self.isInitialized) {
@ -5093,8 +5090,7 @@
// Reset loading flag
self.isLoading = false;
},
error: function(xhr, status, error) {
console.error('SchematicEditor: AJAX error loading connections', error);
error: function() {
self.isLoading = false;
}
});
@ -5161,7 +5157,12 @@
initCanvas: function() {
var $canvas = $('.schematic-editor-canvas');
if (!$canvas.length) return;
if (!$canvas.length) {
return;
}
// Loading message
$canvas.html('<div style="padding:20px;color:#888;">Initialisiere Schaltplan-Editor...</div>');
// Calculate layout first
this.calculateLayout();
@ -5331,12 +5332,9 @@
var blockHtml = '';
var terminalHtml = '';
console.log('SchematicEditor renderBlocks: Processing ' + this.equipment.length + ' equipment');
this.equipment.forEach(function(eq) {
var carrier = self.carriers.find(function(c) { return String(c.id) === String(eq.carrier_id); });
if (!carrier) {
console.log(' Equipment #' + eq.id + ' (' + eq.label + '): No carrier found for carrier_id=' + eq.carrier_id);
return;
}
if (typeof carrier._x === 'undefined' || carrier._x === null) {
@ -5396,6 +5394,7 @@
var coveredByBusbar = self.isEquipmentCoveredByBusbar(eq);
// Top terminals - im TE-Raster platziert (hide if busbar covers this equipment)
var terminalColor = '#666'; // Grau wie die Hutschienen
if (!coveredByBusbar) {
topTerminals.forEach(function(term, idx) {
// Berechne welches TE dieser Terminal belegt (0-basiert)
@ -5403,13 +5402,12 @@
// Terminal ist in der Mitte des jeweiligen TE
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
var ty = y - 7;
var termColor = self.PHASE_COLORS[term.label] || '#3498db';
terminalHtml += '<g class="schematic-terminal" ';
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
terminalHtml += 'transform="translate(' + tx + ',' + ty + ')">';
terminalHtml += '<circle r="' + self.TERMINAL_RADIUS + '" fill="' + termColor + '" stroke="#fff" stroke-width="2" class="schematic-terminal-circle"/>';
terminalHtml += '<circle r="' + self.TERMINAL_RADIUS + '" fill="' + terminalColor + '" stroke="#fff" stroke-width="2" class="schematic-terminal-circle"/>';
terminalHtml += '<text y="-14" text-anchor="middle" fill="#aaa" font-size="11">' + self.escapeHtml(term.label) + '</text>';
terminalHtml += '</g>';
});
@ -5422,13 +5420,12 @@
// Terminal ist in der Mitte des jeweiligen TE
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
var ty = y + blockHeight + 7;
var termColor = self.PHASE_COLORS[term.label] || '#27ae60';
terminalHtml += '<g class="schematic-terminal" ';
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
terminalHtml += 'transform="translate(' + tx + ',' + ty + ')">';
terminalHtml += '<circle r="' + self.TERMINAL_RADIUS + '" fill="' + termColor + '" stroke="#fff" stroke-width="2" class="schematic-terminal-circle"/>';
terminalHtml += '<circle r="' + self.TERMINAL_RADIUS + '" fill="' + terminalColor + '" stroke="#fff" stroke-width="2" class="schematic-terminal-circle"/>';
terminalHtml += '<text y="21" text-anchor="middle" fill="#aaa" font-size="11">' + self.escapeHtml(term.label) + '</text>';
terminalHtml += '</g>';
});
@ -5447,11 +5444,6 @@
var html = '';
var renderedCount = 0;
// Debug: list all connections with is_rail
var busbars = this.connections.filter(function(c) { return parseInt(c.is_rail) === 1; });
console.log('SchematicEditor renderBusbars: Found ' + busbars.length + ' busbars in connections:', busbars);
console.log('SchematicEditor renderBusbars: Carriers available:', this.carriers.map(function(c) { return {id: c.id, _x: c._x, _y: c._y}; }));
// First, group busbars by carrier and position for stacking
var busbarsByCarrierAndPos = {};
this.connections.forEach(function(conn) {
@ -5612,8 +5604,6 @@
', x=' + startX + ', y=' + busbarY + ', width=' + width + ', color=' + color);
});
console.log('SchematicEditor renderBusbars: Rendered ' + renderedCount + ' busbars');
$layer.html(html);
},
@ -5625,8 +5615,6 @@
var html = '';
var renderedCount = 0;
console.log('SchematicEditor renderConnections: Processing ' + this.connections.length + ' connections');
this.connections.forEach(function(conn, connIndex) {
// Check is_rail as integer (PHP may return string "1" or "0")
if (parseInt(conn.is_rail) === 1) {
@ -5844,7 +5832,6 @@
renderedCount++;
});
console.log('SchematicEditor renderConnections: Rendered ' + renderedCount + ' connections');
$layer.html(html);
// Bind click events to SVG connection elements (must be done after rendering)
@ -8205,6 +8192,213 @@
$('.schematic-equipment-popup').remove();
},
showCarrierPopup: function(carrierId, x, y) {
var self = this;
// Remove any existing popup
this.hideCarrierPopup();
this.hideEquipmentPopup();
this.hideConnectionPopup();
// Find carrier data
var carrier = this.carriers.find(function(c) { return parseInt(c.id) === parseInt(carrierId); });
if (!carrier) {
console.warn('Carrier not found for id:', carrierId);
return;
}
// Create popup
var popupHtml = '<div class="schematic-carrier-popup" data-carrier-id="' + carrierId + '" style="' +
'position:fixed;left:' + x + 'px;top:' + y + 'px;' +
'background:#2d2d44;border:2px solid #f39c12;border-radius:6px;padding:10px;' +
'box-shadow:0 4px 20px rgba(0,0,0,0.6);z-index:2147483647;display:flex;flex-direction:column;gap:8px;min-width:180px;">';
// Carrier info
popupHtml += '<div style="color:#fff;font-size:12px;border-bottom:1px solid #555;padding-bottom:6px;margin-bottom:2px;">';
popupHtml += '<strong>' + self.escapeHtml(carrier.label || 'Hutschiene') + '</strong>';
popupHtml += '<br><span style="color:#aaa;">' + (carrier.total_te || 12) + ' TE</span>';
popupHtml += '</div>';
// Buttons row
popupHtml += '<div style="display:flex;gap:8px;">';
// Edit button
popupHtml += '<button type="button" class="schematic-carrier-popup-edit" style="' +
'flex:1;background:#f39c12;color:#fff;border:none;border-radius:4px;padding:8px 12px;' +
'cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:5px;">' +
'<i class="fas fa-edit"></i> Bearbeiten</button>';
// Delete button
popupHtml += '<button type="button" class="schematic-carrier-popup-delete" style="' +
'flex:1;background:#e74c3c;color:#fff;border:none;border-radius:4px;padding:8px 12px;' +
'cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:5px;">' +
'<i class="fas fa-trash"></i> Löschen</button>';
popupHtml += '</div></div>';
$('body').append(popupHtml);
// Bind button events
$('.schematic-carrier-popup-edit').on('click', function(e) {
e.stopPropagation();
self.editCarrier(carrierId);
});
$('.schematic-carrier-popup-delete').on('click', function(e) {
e.stopPropagation();
self.hideCarrierPopup();
self.deleteCarrier(carrierId);
});
// Adjust position if popup goes off screen
var $popup = $('.schematic-carrier-popup');
var popupWidth = $popup.outerWidth();
var popupHeight = $popup.outerHeight();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
if (x + popupWidth > windowWidth - 10) {
$popup.css('left', (x - popupWidth) + 'px');
}
if (y + popupHeight > windowHeight - 10) {
$popup.css('top', (y - popupHeight) + 'px');
}
},
hideCarrierPopup: function() {
$('.schematic-carrier-popup').remove();
},
editCarrier: function(carrierId) {
var self = this;
// Hide popup first
this.hideCarrierPopup();
// Find carrier data
var carrier = this.carriers.find(function(c) { return parseInt(c.id) === parseInt(carrierId); });
if (!carrier) return;
// Load panels for dropdown
$.ajax({
url: baseUrl + '/custom/kundenkarte/ajax/equipment_panel.php',
data: { action: 'list', anlage_id: self.anlageId },
dataType: 'json',
success: function(response) {
var panels = response.success ? response.panels : [];
self.showEditCarrierDialog(carrier, panels);
}
});
},
showEditCarrierDialog: function(carrier, panels) {
var self = this;
// Remove existing dialog
$('.schematic-edit-overlay').remove();
var html = '<div class="schematic-edit-overlay" style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:2147483647;display:flex;align-items:center;justify-content:center;">';
html += '<div class="schematic-edit-dialog" style="background:#2d2d44;border:2px solid #f39c12;border-radius:8px;padding:20px;min-width:350px;max-width:450px;">';
html += '<h3 style="color:#fff;margin:0 0 15px 0;padding-bottom:10px;border-bottom:1px solid #555;">Hutschiene bearbeiten</h3>';
html += '<table style="width:100%;border-collapse:collapse;">';
// Label
html += '<tr><td style="color:#aaa;padding:8px 0;">Bezeichnung</td>';
html += '<td><input type="text" class="carrier-edit-label" value="' + self.escapeHtml(carrier.label || '') + '" style="width:100%;padding:8px;background:#1a1a2e;border:1px solid #555;border-radius:4px;color:#fff;"></td></tr>';
// Total TE
html += '<tr><td style="color:#aaa;padding:8px 0;">Kapazität (TE)</td>';
html += '<td><input type="number" class="carrier-edit-total-te" value="' + (carrier.total_te || 12) + '" min="1" max="72" style="width:100%;padding:8px;background:#1a1a2e;border:1px solid #555;border-radius:4px;color:#fff;"></td></tr>';
// Panel dropdown
if (panels && panels.length > 0) {
html += '<tr><td style="color:#aaa;padding:8px 0;">Feld</td>';
html += '<td><select class="carrier-edit-panel" style="width:100%;padding:8px;background:#1a1a2e;border:1px solid #555;border-radius:4px;color:#fff;">';
html += '<option value="0">-- Kein Feld --</option>';
panels.forEach(function(p) {
var selected = (carrier.panel_id == p.id) ? ' selected' : '';
html += '<option value="' + p.id + '"' + selected + '>' + self.escapeHtml(p.label) + '</option>';
});
html += '</select></td></tr>';
}
html += '</table>';
// Buttons
html += '<div style="margin-top:20px;display:flex;gap:10px;justify-content:flex-end;">';
html += '<button type="button" class="edit-dialog-save" style="background:#f39c12;color:#fff;border:none;border-radius:4px;padding:10px 20px;cursor:pointer;font-size:14px;"><i class="fas fa-save"></i> Speichern</button>';
html += '<button type="button" class="edit-dialog-cancel" style="background:#555;color:#fff;border:none;border-radius:4px;padding:10px 20px;cursor:pointer;font-size:14px;">Abbrechen</button>';
html += '</div>';
html += '</div></div>';
$('body').append(html);
// Save handler
$('.edit-dialog-save').on('click', function() {
var label = $('.carrier-edit-label').val();
var totalTe = parseInt($('.carrier-edit-total-te').val()) || 12;
var panelId = parseInt($('.carrier-edit-panel').val()) || 0;
$.ajax({
url: baseUrl + '/custom/kundenkarte/ajax/equipment_carrier.php',
method: 'POST',
data: {
action: 'update',
carrier_id: carrier.id,
label: label,
total_te: totalTe,
panel_id: panelId
},
dataType: 'json',
success: function(response) {
if (response.success) {
$('.schematic-edit-overlay').remove();
self.loadData(); // Reload all data
} else {
alert('Fehler: ' + (response.error || 'Unbekannter Fehler'));
}
}
});
});
// Cancel handler
$('.edit-dialog-cancel, .schematic-edit-overlay').on('click', function(e) {
if (e.target === this) {
$('.schematic-edit-overlay').remove();
}
});
},
deleteCarrier: function(carrierId) {
var self = this;
// Find carrier data for confirmation
var carrier = this.carriers.find(function(c) { return parseInt(c.id) === parseInt(carrierId); });
var carrierLabel = carrier ? (carrier.label || 'Hutschiene') : 'Hutschiene';
this.showConfirmDialog('Hutschiene löschen', 'Hutschiene "' + carrierLabel + '" wirklich löschen? Alle darauf platzierten Geräte werden ebenfalls gelöscht!', function() {
$.ajax({
url: baseUrl + '/custom/kundenkarte/ajax/equipment_carrier.php',
method: 'POST',
data: {
action: 'delete',
carrier_id: carrierId
},
dataType: 'json',
success: function(response) {
if (response.success) {
self.loadData(); // Reload all data
} else {
alert('Fehler: ' + (response.error || 'Unbekannter Fehler'));
}
}
});
});
},
editEquipment: function(equipmentId) {
var self = this;