Compare commits
2 commits
10dbf420c3
...
2995b8fa4e
| Author | SHA1 | Date | |
|---|---|---|---|
| 2995b8fa4e | |||
| 49087bf8f6 |
4 changed files with 247 additions and 37 deletions
11
README.md
11
README.md
|
|
@ -17,6 +17,16 @@ Das KundenKarte-Modul erweitert Dolibarr um zwei wichtige Funktionen fuer Kunden
|
||||||
- Datei-Upload mit Bild-Vorschau und PDF-Anzeige
|
- Datei-Upload mit Bild-Vorschau und PDF-Anzeige
|
||||||
- Separate Verwaltung pro Kunde oder pro Kontakt/Adresse (z.B. verschiedene Gebaeude)
|
- Separate Verwaltung pro Kunde oder pro Kontakt/Adresse (z.B. verschiedene Gebaeude)
|
||||||
|
|
||||||
|
### Verteilungsdokumentation (Schaltplan-Editor)
|
||||||
|
- Interaktiver SVG-basierter Schaltplan-Editor
|
||||||
|
- Felder (Panels) und Hutschienen visuell verwalten
|
||||||
|
- Equipment-Bloecke per Drag & Drop positionieren
|
||||||
|
- Sammelschienen (Busbars) fuer Phasenverteilung
|
||||||
|
- Verbindungen zwischen Geraeten zeichnen
|
||||||
|
- Abgaenge und Anschlusspunkte dokumentieren
|
||||||
|
- Klickbare Hutschienen zum Bearbeiten
|
||||||
|
- Zoom und Pan fuer grosse Schaltplaene
|
||||||
|
|
||||||
### PDF Export
|
### PDF Export
|
||||||
- Export der Anlagenstruktur als PDF
|
- Export der Anlagenstruktur als PDF
|
||||||
- Upload einer PDF-Vorlage als Briefpapier/Hintergrund
|
- Upload einer PDF-Vorlage als Briefpapier/Hintergrund
|
||||||
|
|
@ -46,6 +56,7 @@ Im Admin-Bereich (Home > Setup > Module > KundenKarte) koennen Sie:
|
||||||
- **Anlagen-Systeme**: System-Kategorien anlegen (z.B. Strom, Internet)
|
- **Anlagen-Systeme**: System-Kategorien anlegen (z.B. Strom, Internet)
|
||||||
- **Element-Typen**: Geraetetypen definieren (z.B. Zaehler, Router, Wallbox)
|
- **Element-Typen**: Geraetetypen definieren (z.B. Zaehler, Router, Wallbox)
|
||||||
- **Typ-Felder**: Individuelle Felder pro Geraetetyp konfigurieren
|
- **Typ-Felder**: Individuelle Felder pro Geraetetyp konfigurieren
|
||||||
|
- **Equipment-Typen**: Schaltplan-Komponenten (z.B. Sicherungsautomaten, FI-Schalter) mit Breite (TE), Farbe und Terminal-Konfiguration
|
||||||
|
|
||||||
## Berechtigungen
|
## Berechtigungen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class modKundenKarte extends DolibarrModules
|
||||||
$this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@kundenkarte'
|
$this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@kundenkarte'
|
||||||
|
|
||||||
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
|
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
|
||||||
$this->version = '3.0';
|
$this->version = '3.1';
|
||||||
// Url to the file with your last numberversion of this module
|
// Url to the file with your last numberversion of this module
|
||||||
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
|
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1652,7 +1652,12 @@
|
||||||
|
|
||||||
/* Rails (Hutschienen) */
|
/* Rails (Hutschienen) */
|
||||||
.schematic-rail {
|
.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 {
|
.schematic-rail-bg {
|
||||||
|
|
|
||||||
|
|
@ -4465,7 +4465,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function(anlageId) {
|
init: function(anlageId) {
|
||||||
if (!anlageId) return;
|
if (!anlageId) {
|
||||||
|
console.error('SchematicEditor.init: No anlageId provided!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.anlageId = anlageId;
|
this.anlageId = anlageId;
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
this.loadData();
|
this.loadData();
|
||||||
|
|
@ -4528,7 +4531,7 @@
|
||||||
// Hide popups when clicking elsewhere
|
// Hide popups when clicking elsewhere
|
||||||
$(document).off('mousedown.hidePopup').on('mousedown.hidePopup', function(e) {
|
$(document).off('mousedown.hidePopup').on('mousedown.hidePopup', function(e) {
|
||||||
// Don't hide if clicking on popup buttons
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
// Don't hide if clicking on SVG elements (handlers will handle it)
|
// Don't hide if clicking on SVG elements (handlers will handle it)
|
||||||
|
|
@ -4537,6 +4540,7 @@
|
||||||
}
|
}
|
||||||
self.hideConnectionPopup();
|
self.hideConnectionPopup();
|
||||||
self.hideEquipmentPopup();
|
self.hideEquipmentPopup();
|
||||||
|
self.hideCarrierPopup();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear all connections
|
// Clear all connections
|
||||||
|
|
@ -4584,12 +4588,14 @@
|
||||||
self.showBusbarPopup(connectionId, e.clientX, e.clientY);
|
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) {
|
$(document).off('click.rail').on('click.rail', '.schematic-rail', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
var carrierId = $(this).data('carrier-id');
|
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
|
// Terminal right-click - show output/cable dialog
|
||||||
|
|
@ -4989,11 +4995,9 @@
|
||||||
|
|
||||||
// Prevent multiple simultaneous loads (race condition fix)
|
// Prevent multiple simultaneous loads (race condition fix)
|
||||||
if (this.isLoading) {
|
if (this.isLoading) {
|
||||||
console.log('SchematicEditor loadData: Already loading, skipping...');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
console.log('SchematicEditor loadData: Starting...');
|
|
||||||
|
|
||||||
// Load panels with carriers for this anlage
|
// Load panels with carriers for this anlage
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
@ -5003,7 +5007,6 @@
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
self.panels = response.panels || [];
|
self.panels = response.panels || [];
|
||||||
console.log('SchematicEditor loadData: Loaded ' + self.panels.length + ' panels');
|
|
||||||
// Flatten carriers from all panels
|
// Flatten carriers from all panels
|
||||||
self.carriers = [];
|
self.carriers = [];
|
||||||
self.panels.forEach(function(panel) {
|
self.panels.forEach(function(panel) {
|
||||||
|
|
@ -5014,16 +5017,15 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('SchematicEditor loadData: Loaded ' + self.carriers.length + ' carriers');
|
|
||||||
self.loadEquipment();
|
self.loadEquipment();
|
||||||
} else {
|
} else {
|
||||||
console.error('SchematicEditor loadData: Failed to load panels', response);
|
|
||||||
self.isLoading = false;
|
self.isLoading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
console.error('SchematicEditor loadData: AJAX error', error);
|
|
||||||
self.isLoading = false;
|
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() {
|
$.when.apply($, promises).then(function() {
|
||||||
self.loadConnections();
|
self.loadConnections();
|
||||||
}).fail(function() {
|
}).fail(function() {
|
||||||
console.error('SchematicEditor loadEquipment: One or more AJAX requests failed');
|
|
||||||
self.isLoading = false;
|
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
|
// Initialize canvas now that all data is loaded
|
||||||
if (!self.isInitialized) {
|
if (!self.isInitialized) {
|
||||||
|
|
@ -5093,8 +5090,7 @@
|
||||||
// Reset loading flag
|
// Reset loading flag
|
||||||
self.isLoading = false;
|
self.isLoading = false;
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function() {
|
||||||
console.error('SchematicEditor: AJAX error loading connections', error);
|
|
||||||
self.isLoading = false;
|
self.isLoading = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -5161,7 +5157,12 @@
|
||||||
initCanvas: function() {
|
initCanvas: function() {
|
||||||
var $canvas = $('.schematic-editor-canvas');
|
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
|
// Calculate layout first
|
||||||
this.calculateLayout();
|
this.calculateLayout();
|
||||||
|
|
@ -5331,12 +5332,9 @@
|
||||||
var blockHtml = '';
|
var blockHtml = '';
|
||||||
var terminalHtml = '';
|
var terminalHtml = '';
|
||||||
|
|
||||||
console.log('SchematicEditor renderBlocks: Processing ' + this.equipment.length + ' equipment');
|
|
||||||
|
|
||||||
this.equipment.forEach(function(eq) {
|
this.equipment.forEach(function(eq) {
|
||||||
var carrier = self.carriers.find(function(c) { return String(c.id) === String(eq.carrier_id); });
|
var carrier = self.carriers.find(function(c) { return String(c.id) === String(eq.carrier_id); });
|
||||||
if (!carrier) {
|
if (!carrier) {
|
||||||
console.log(' Equipment #' + eq.id + ' (' + eq.label + '): No carrier found for carrier_id=' + eq.carrier_id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof carrier._x === 'undefined' || carrier._x === null) {
|
if (typeof carrier._x === 'undefined' || carrier._x === null) {
|
||||||
|
|
@ -5396,6 +5394,7 @@
|
||||||
var coveredByBusbar = self.isEquipmentCoveredByBusbar(eq);
|
var coveredByBusbar = self.isEquipmentCoveredByBusbar(eq);
|
||||||
|
|
||||||
// Top terminals - im TE-Raster platziert (hide if busbar covers this equipment)
|
// Top terminals - im TE-Raster platziert (hide if busbar covers this equipment)
|
||||||
|
var terminalColor = '#666'; // Grau wie die Hutschienen
|
||||||
if (!coveredByBusbar) {
|
if (!coveredByBusbar) {
|
||||||
topTerminals.forEach(function(term, idx) {
|
topTerminals.forEach(function(term, idx) {
|
||||||
// Berechne welches TE dieser Terminal belegt (0-basiert)
|
// Berechne welches TE dieser Terminal belegt (0-basiert)
|
||||||
|
|
@ -5403,13 +5402,12 @@
|
||||||
// Terminal ist in der Mitte des jeweiligen TE
|
// Terminal ist in der Mitte des jeweiligen TE
|
||||||
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
|
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
|
||||||
var ty = y - 7;
|
var ty = y - 7;
|
||||||
var termColor = self.PHASE_COLORS[term.label] || '#3498db';
|
|
||||||
|
|
||||||
terminalHtml += '<g class="schematic-terminal" ';
|
terminalHtml += '<g class="schematic-terminal" ';
|
||||||
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
|
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
|
||||||
terminalHtml += 'transform="translate(' + tx + ',' + ty + ')">';
|
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 += '<text y="-14" text-anchor="middle" fill="#aaa" font-size="11">' + self.escapeHtml(term.label) + '</text>';
|
||||||
terminalHtml += '</g>';
|
terminalHtml += '</g>';
|
||||||
});
|
});
|
||||||
|
|
@ -5422,13 +5420,12 @@
|
||||||
// Terminal ist in der Mitte des jeweiligen TE
|
// Terminal ist in der Mitte des jeweiligen TE
|
||||||
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
|
var tx = x + (teIndex * self.TE_WIDTH) + (self.TE_WIDTH / 2);
|
||||||
var ty = y + blockHeight + 7;
|
var ty = y + blockHeight + 7;
|
||||||
var termColor = self.PHASE_COLORS[term.label] || '#27ae60';
|
|
||||||
|
|
||||||
terminalHtml += '<g class="schematic-terminal" ';
|
terminalHtml += '<g class="schematic-terminal" ';
|
||||||
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
|
terminalHtml += 'data-equipment-id="' + eq.id + '" data-terminal-id="' + term.id + '" ';
|
||||||
terminalHtml += 'transform="translate(' + tx + ',' + ty + ')">';
|
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 += '<text y="21" text-anchor="middle" fill="#aaa" font-size="11">' + self.escapeHtml(term.label) + '</text>';
|
||||||
terminalHtml += '</g>';
|
terminalHtml += '</g>';
|
||||||
});
|
});
|
||||||
|
|
@ -5447,11 +5444,6 @@
|
||||||
var html = '';
|
var html = '';
|
||||||
var renderedCount = 0;
|
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
|
// First, group busbars by carrier and position for stacking
|
||||||
var busbarsByCarrierAndPos = {};
|
var busbarsByCarrierAndPos = {};
|
||||||
this.connections.forEach(function(conn) {
|
this.connections.forEach(function(conn) {
|
||||||
|
|
@ -5612,8 +5604,6 @@
|
||||||
', x=' + startX + ', y=' + busbarY + ', width=' + width + ', color=' + color);
|
', x=' + startX + ', y=' + busbarY + ', width=' + width + ', color=' + color);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('SchematicEditor renderBusbars: Rendered ' + renderedCount + ' busbars');
|
|
||||||
|
|
||||||
$layer.html(html);
|
$layer.html(html);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -5625,8 +5615,6 @@
|
||||||
var html = '';
|
var html = '';
|
||||||
var renderedCount = 0;
|
var renderedCount = 0;
|
||||||
|
|
||||||
console.log('SchematicEditor renderConnections: Processing ' + this.connections.length + ' connections');
|
|
||||||
|
|
||||||
this.connections.forEach(function(conn, connIndex) {
|
this.connections.forEach(function(conn, connIndex) {
|
||||||
// Check is_rail as integer (PHP may return string "1" or "0")
|
// Check is_rail as integer (PHP may return string "1" or "0")
|
||||||
if (parseInt(conn.is_rail) === 1) {
|
if (parseInt(conn.is_rail) === 1) {
|
||||||
|
|
@ -5844,7 +5832,6 @@
|
||||||
renderedCount++;
|
renderedCount++;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('SchematicEditor renderConnections: Rendered ' + renderedCount + ' connections');
|
|
||||||
$layer.html(html);
|
$layer.html(html);
|
||||||
|
|
||||||
// Bind click events to SVG connection elements (must be done after rendering)
|
// Bind click events to SVG connection elements (must be done after rendering)
|
||||||
|
|
@ -8205,6 +8192,213 @@
|
||||||
$('.schematic-equipment-popup').remove();
|
$('.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) {
|
editEquipment: function(equipmentId) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue