diff --git a/css/kundenkarte.css b/css/kundenkarte.css
index a8bbe02..d8a170a 100755
--- a/css/kundenkarte.css
+++ b/css/kundenkarte.css
@@ -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 {
diff --git a/js/kundenkarte.js b/js/kundenkarte.js
index 28a17bd..95c686b 100755
--- a/js/kundenkarte.js
+++ b/js/kundenkarte.js
@@ -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('
AJAX Fehler beim Laden: ' + error + '
');
}
});
},
@@ -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('Initialisiere Schaltplan-Editor...
');
// 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 += '';
- terminalHtml += '';
+ terminalHtml += '';
terminalHtml += '' + self.escapeHtml(term.label) + '';
terminalHtml += '';
});
@@ -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 += '';
- terminalHtml += '';
+ terminalHtml += '';
terminalHtml += '' + self.escapeHtml(term.label) + '';
terminalHtml += '';
});
@@ -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 = '';
+
+ $('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 = '';
+ html += '
';
+
+ html += '
Hutschiene bearbeiten
';
+
+ html += '
';
+
+ // Buttons
+ html += '
';
+ html += '';
+ html += '';
+ html += '
';
+
+ html += '
';
+
+ $('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;