From 95e18609404ce969e9ce22995ab745ea916e0658 Mon Sep 17 00:00:00 2001 From: data Date: Wed, 4 Mar 2026 15:35:25 +0100 Subject: [PATCH] Anschlusspunkt Fix --- admin/busbar_types.php | 28 +++ ajax/busbar_types.php | 71 +++++++ ajax/equipment_connection.php | 8 + class/busbartype.class.php | 6 +- class/equipmentconnection.class.php | 14 +- core/modules/modKundenKarte.class.php | 45 ++++ js/kundenkarte.js | 286 +++++++++++++++++++------- js/pwa.js | 4 +- sw.js | 4 +- 9 files changed, 383 insertions(+), 83 deletions(-) create mode 100644 ajax/busbar_types.php diff --git a/admin/busbar_types.php b/admin/busbar_types.php index d44d80e..ead72df 100644 --- a/admin/busbar_types.php +++ b/admin/busbar_types.php @@ -85,6 +85,12 @@ if ($action == 'add') { $busbarType->description = GETPOST('description', 'restricthtml'); $busbarType->fk_system = GETPOSTINT('fk_system'); $busbarType->phases = GETPOST('phases', 'alphanohtml'); + // Convert comma-separated phases_config to JSON array + $phasesConfigInput = GETPOST('phases_config', 'alphanohtml'); + if (!empty($phasesConfigInput)) { + $arr = array_map('trim', explode(',', $phasesConfigInput)); + $busbarType->phases_config = json_encode($arr); + } $busbarType->num_lines = GETPOSTINT('num_lines'); $busbarType->color = GETPOST('color', 'alphanohtml'); $busbarType->default_color = GETPOST('default_color', 'alphanohtml'); @@ -120,6 +126,14 @@ if ($action == 'update') { $busbarType->description = GETPOST('description', 'restricthtml'); $busbarType->fk_system = GETPOSTINT('fk_system'); $busbarType->phases = GETPOST('phases', 'alphanohtml'); + // Convert comma-separated phases_config to JSON array + $phasesConfigInput = GETPOST('phases_config', 'alphanohtml'); + if (!empty($phasesConfigInput)) { + $arr = array_map('trim', explode(',', $phasesConfigInput)); + $busbarType->phases_config = json_encode($arr); + } else { + $busbarType->phases_config = null; + } $busbarType->num_lines = GETPOSTINT('num_lines'); $busbarType->color = GETPOST('color', 'alphanohtml'); $busbarType->default_color = GETPOST('default_color', 'alphanohtml'); @@ -267,6 +281,20 @@ if ($action == 'create' || $action == 'edit') { print ''.$langs->trans('NumLines').''; print ''; + // Phase labels per line (phases_config) + $phasesConfigVal = ''; + if (!empty($busbarType->phases_config)) { + $arr = json_decode($busbarType->phases_config, true); + if (is_array($arr)) { + $phasesConfigVal = implode(',', $arr); + } + } + print ''.$langs->trans('PhaseLabels').''; + print ''; + print ''; + print '
Kommagetrennte Bezeichnungen pro Linie, wiederholen sich (z.B. L1,L2,L3 oder L1,N)
'; + print ''; + // Colors print ''.$langs->trans('Colors').''; print ''; diff --git a/ajax/busbar_types.php b/ajax/busbar_types.php new file mode 100644 index 0000000..6109464 --- /dev/null +++ b/ajax/busbar_types.php @@ -0,0 +1,71 @@ +loadLangs(array('kundenkarte@kundenkarte')); + +$action = GETPOST('action', 'aZ09'); +$systemId = GETPOSTINT('system_id'); + +$response = array('success' => false, 'error' => ''); + +// Security check +if (!$user->hasRight('kundenkarte', 'read')) { + $response['error'] = $langs->trans('ErrorPermissionDenied'); + echo json_encode($response); + exit; +} + +$busbarType = new BusbarType($db); + +switch ($action) { + case 'list': + // Get all busbar types for a system (or all if system_id = 0) + $types = $busbarType->fetchAllBySystem($systemId, 1); + + $result = array(); + foreach ($types as $t) { + $result[] = array( + 'id' => $t->id, + 'ref' => $t->ref, + 'label' => $t->label, + 'label_short' => $t->label_short, + 'phases' => $t->phases, + 'phases_config' => $t->phases_config ? json_decode($t->phases_config, true) : null, + 'num_lines' => $t->num_lines, + 'color' => $t->color, + 'default_color' => $t->default_color, + 'line_height' => $t->line_height, + 'line_spacing' => $t->line_spacing, + 'position_default' => $t->position_default, + 'fk_system' => $t->fk_system, + 'system_label' => $t->system_label + ); + } + + $response['success'] = true; + $response['types'] = $result; + break; + + default: + $response['error'] = 'Unknown action'; + break; +} + +echo json_encode($response); diff --git a/ajax/equipment_connection.php b/ajax/equipment_connection.php index fbeb776..91f5ff3 100644 --- a/ajax/equipment_connection.php +++ b/ajax/equipment_connection.php @@ -102,6 +102,8 @@ switch ($action) { 'rail_phases' => $c->rail_phases, 'excluded_te' => $c->excluded_te, 'position_y' => $c->position_y, + 'fk_busbar_type' => $c->fk_busbar_type, + 'phases_config' => $c->phases_config ? json_decode($c->phases_config, true) : null, 'display_label' => $c->getDisplayLabel() ); } @@ -196,6 +198,7 @@ switch ($action) { if (GETPOSTISSET('position_y')) $connection->position_y = GETPOSTINT('position_y'); if (GETPOSTISSET('path_data')) $connection->path_data = GETPOST('path_data', 'nohtml'); if (GETPOSTISSET('bundled_terminals')) $connection->bundled_terminals = GETPOST('bundled_terminals', 'alphanohtml'); + if (GETPOSTISSET('fk_busbar_type')) $connection->fk_busbar_type = GETPOSTINT('fk_busbar_type') ?: null; $result = $connection->update($user); if ($result > 0) { @@ -239,6 +242,8 @@ switch ($action) { $connection->rail_end_te = GETPOSTINT('rail_end_te'); $connection->rail_phases = GETPOST('rail_phases', 'alphanohtml'); $connection->excluded_te = GETPOST('excluded_te', 'alphanohtml'); + $connection->num_lines = GETPOSTINT('num_lines') ?: 1; + $connection->fk_busbar_type = GETPOSTINT('fk_busbar_type') ?: null; $connection->fk_carrier = $carrierId; $connection->position_y = GETPOSTINT('position_y'); @@ -248,6 +253,7 @@ switch ($action) { $response['connection_id'] = $result; } else { $response['error'] = $connection->error ?: 'Create failed'; + $response['sql_errors'] = $connection->errors; } break; @@ -368,6 +374,8 @@ switch ($action) { 'rail_start_te' => $obj->rail_start_te, 'rail_end_te' => $obj->rail_end_te, 'rail_phases' => $obj->rail_phases, + 'num_lines' => isset($obj->num_lines) ? $obj->num_lines : 1, + 'fk_busbar_type' => isset($obj->fk_busbar_type) ? $obj->fk_busbar_type : null, 'position_y' => $obj->position_y, 'fk_carrier' => $obj->fk_carrier, 'path_data' => isset($obj->path_data) ? $obj->path_data : null diff --git a/class/busbartype.class.php b/class/busbartype.class.php index 2c769ee..7d93508 100644 --- a/class/busbartype.class.php +++ b/class/busbartype.class.php @@ -24,6 +24,7 @@ class BusbarType extends CommonObject // Busbar-spezifische Felder public $phases; // Channel configuration (A, B, AB, ABC, or legacy L1, L2, L3, N, PE, etc.) + public $phases_config; // JSON array of phase labels per line, e.g. ["L1","L2","L3"] public $num_lines = 1; // Anzahl der Linien public $color; // Kommagetrennte Farben public $default_color; // Standard-Einzelfarbe @@ -80,7 +81,7 @@ class BusbarType extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; $sql .= "entity, ref, label, label_short, description, fk_system,"; - $sql .= " phases, num_lines, color, default_color, line_height, line_spacing, position_default,"; + $sql .= " phases, phases_config, num_lines, color, default_color, line_height, line_spacing, position_default,"; $sql .= " fk_product, picto, icon_file, is_system, position, active,"; $sql .= " date_creation, fk_user_creat"; $sql .= ") VALUES ("; @@ -91,6 +92,7 @@ class BusbarType extends CommonObject $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "NULL"); $sql .= ", ".((int) $this->fk_system); $sql .= ", '".$this->db->escape($this->phases)."'"; + $sql .= ", ".($this->phases_config ? "'".$this->db->escape($this->phases_config)."'" : "NULL"); $sql .= ", ".((int) ($this->num_lines > 0 ? $this->num_lines : 1)); $sql .= ", ".($this->color ? "'".$this->db->escape($this->color)."'" : "NULL"); $sql .= ", ".($this->default_color ? "'".$this->db->escape($this->default_color)."'" : "NULL"); @@ -206,6 +208,7 @@ class BusbarType extends CommonObject $sql .= ", description = ".($this->description ? "'".$this->db->escape($this->description)."'" : "NULL"); $sql .= ", fk_system = ".((int) $this->fk_system); $sql .= ", phases = '".$this->db->escape($this->phases)."'"; + $sql .= ", phases_config = ".($this->phases_config ? "'".$this->db->escape($this->phases_config)."'" : "NULL"); $sql .= ", num_lines = ".((int) ($this->num_lines > 0 ? $this->num_lines : 1)); $sql .= ", color = ".($this->color ? "'".$this->db->escape($this->color)."'" : "NULL"); $sql .= ", default_color = ".($this->default_color ? "'".$this->db->escape($this->default_color)."'" : "NULL"); @@ -316,6 +319,7 @@ class BusbarType extends CommonObject $type->label_short = $obj->label_short; $type->fk_system = $obj->fk_system; $type->phases = $obj->phases; + $type->phases_config = $obj->phases_config; $type->num_lines = $obj->num_lines; $type->color = $obj->color; $type->default_color = $obj->default_color; diff --git a/class/equipmentconnection.class.php b/class/equipmentconnection.class.php index b22924a..0326414 100644 --- a/class/equipmentconnection.class.php +++ b/class/equipmentconnection.class.php @@ -42,6 +42,9 @@ class EquipmentConnection extends CommonObject public $rail_end_te; public $rail_phases; // '3P', '3P+N', 'L1', 'L1N', etc. public $excluded_te; // Comma-separated TE positions to exclude (gaps for FI) + public $num_lines = 1; // Number of lines for busbar (1-5) + public $fk_busbar_type; // Reference to busbar type template + public $phases_config; // JSON array of phase labels from busbar type public $fk_carrier; public $position_y = 0; @@ -90,7 +93,7 @@ class EquipmentConnection extends CommonObject $sql .= "entity, fk_source, source_terminal, source_terminal_id, bundled_terminals, fk_target, target_terminal, target_terminal_id,"; $sql .= " connection_type, color, output_label,"; $sql .= " medium_type, medium_spec, medium_length,"; - $sql .= " is_rail, rail_start_te, rail_end_te, rail_phases, excluded_te, fk_carrier, position_y, path_data,"; + $sql .= " is_rail, rail_start_te, rail_end_te, rail_phases, excluded_te, num_lines, fk_busbar_type, fk_carrier, position_y, path_data,"; $sql .= " note_private, status, date_creation, fk_user_creat"; $sql .= ") VALUES ("; $sql .= ((int) $conf->entity); @@ -112,6 +115,8 @@ class EquipmentConnection extends CommonObject $sql .= ", ".($this->rail_end_te > 0 ? ((int) $this->rail_end_te) : "NULL"); $sql .= ", ".($this->rail_phases ? "'".$this->db->escape($this->rail_phases)."'" : "NULL"); $sql .= ", ".($this->excluded_te ? "'".$this->db->escape($this->excluded_te)."'" : "NULL"); + $sql .= ", ".((int) ($this->num_lines > 0 ? $this->num_lines : 1)); + $sql .= ", ".($this->fk_busbar_type > 0 ? ((int) $this->fk_busbar_type) : "NULL"); $sql .= ", ".($this->fk_carrier > 0 ? ((int) $this->fk_carrier) : "NULL"); $sql .= ", ".((int) $this->position_y); $sql .= ", ".($this->path_data ? "'".$this->db->escape($this->path_data)."'" : "NULL"); @@ -237,6 +242,7 @@ class EquipmentConnection extends CommonObject $sql .= ", rail_end_te = ".($this->rail_end_te > 0 ? ((int) $this->rail_end_te) : "NULL"); $sql .= ", rail_phases = ".($this->rail_phases ? "'".$this->db->escape($this->rail_phases)."'" : "NULL"); $sql .= ", excluded_te = ".($this->excluded_te ? "'".$this->db->escape($this->excluded_te)."'" : "NULL"); + $sql .= ", fk_busbar_type = ".($this->fk_busbar_type > 0 ? ((int) $this->fk_busbar_type) : "NULL"); $sql .= ", fk_carrier = ".($this->fk_carrier > 0 ? ((int) $this->fk_carrier) : "NULL"); $sql .= ", position_y = ".((int) $this->position_y); $sql .= ", path_data = ".($this->path_data ? "'".$this->db->escape($this->path_data)."'" : "NULL"); @@ -300,10 +306,12 @@ class EquipmentConnection extends CommonObject $sql = "SELECT c.*, "; $sql .= " src.label as source_label, src.position_te as source_pos, src.width_te as source_width,"; - $sql .= " tgt.label as target_label, tgt.position_te as target_pos"; + $sql .= " tgt.label as target_label, tgt.position_te as target_pos,"; + $sql .= " bt.phases_config as busbar_phases_config"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment as src ON c.fk_source = src.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment as tgt ON c.fk_target = tgt.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_busbar_type as bt ON c.fk_busbar_type = bt.rowid"; $sql .= " WHERE c.fk_carrier = ".((int) $carrierId); if ($activeOnly) { $sql .= " AND c.status = 1"; @@ -344,6 +352,8 @@ class EquipmentConnection extends CommonObject $conn->source_width = $obj->source_width; $conn->target_label = $obj->target_label; $conn->target_pos = $obj->target_pos; + $conn->fk_busbar_type = isset($obj->fk_busbar_type) ? $obj->fk_busbar_type : null; + $conn->phases_config = isset($obj->busbar_phases_config) ? $obj->busbar_phases_config : null; $results[] = $conn; } diff --git a/core/modules/modKundenKarte.class.php b/core/modules/modKundenKarte.class.php index 101ca14..788a876 100644 --- a/core/modules/modKundenKarte.class.php +++ b/core/modules/modKundenKarte.class.php @@ -659,6 +659,9 @@ class modKundenKarte extends DolibarrModules // v8.6.0: has_product Flag für Typen $this->migrate_v860_has_product(); + + // v11.0.0: Busbar type reference and num_lines for connections + $this->migrate_v1100_busbar_fields(); } /** @@ -1048,6 +1051,48 @@ class modKundenKarte extends DolibarrModules } } + /** + * Migration v11.0.0: Add busbar type fields to connections + */ + private function migrate_v1100_busbar_fields() + { + $table = MAIN_DB_PREFIX."kundenkarte_equipment_connection"; + + // Check if table exists + $resql = $this->db->query("SHOW TABLES LIKE '".$this->db->escape($table)."'"); + if (!$resql || $this->db->num_rows($resql) == 0) { + return; + } + + // Add num_lines column + $resql = $this->db->query("SHOW COLUMNS FROM ".$table." LIKE 'num_lines'"); + if (!$resql || $this->db->num_rows($resql) == 0) { + $this->db->query("ALTER TABLE ".$table." ADD COLUMN num_lines int(11) DEFAULT 1 AFTER excluded_te"); + } + + // Add fk_busbar_type column + $resql = $this->db->query("SHOW COLUMNS FROM ".$table." LIKE 'fk_busbar_type'"); + if (!$resql || $this->db->num_rows($resql) == 0) { + $this->db->query("ALTER TABLE ".$table." ADD COLUMN fk_busbar_type int(11) DEFAULT NULL AFTER num_lines"); + } + + // Extend color column to support comma-separated colors for multi-line busbars + $resql = $this->db->query("SHOW COLUMNS FROM ".$table." WHERE Field = 'color' AND Type LIKE 'varchar(20)%'"); + if ($resql && $this->db->num_rows($resql) > 0) { + $this->db->query("ALTER TABLE ".$table." MODIFY COLUMN color varchar(255)"); + } + + // Add phases_config column to busbar_type table + $busbarTable = MAIN_DB_PREFIX."kundenkarte_busbar_type"; + $resql = $this->db->query("SHOW TABLES LIKE '".$this->db->escape($busbarTable)."'"); + if ($resql && $this->db->num_rows($resql) > 0) { + $resql2 = $this->db->query("SHOW COLUMNS FROM ".$busbarTable." LIKE 'phases_config'"); + if (!$resql2 || $this->db->num_rows($resql2) == 0) { + $this->db->query("ALTER TABLE ".$busbarTable." ADD COLUMN phases_config TEXT DEFAULT NULL AFTER phases"); + } + } + } + /** * Function called when module is disabled. * Remove from database constants, boxes and permissions from Dolibarr database. diff --git a/js/kundenkarte.js b/js/kundenkarte.js index 0e0f32d..cde2100 100644 --- a/js/kundenkarte.js +++ b/js/kundenkarte.js @@ -5195,6 +5195,7 @@ equipment: [], connections: [], bridges: [], // Terminal bridges (Brücken zwischen Klemmen) + busbarTypes: [], // Sammelschienen-Typen aus Datenbank selectedTerminal: null, dragState: null, isInitialized: false, @@ -5276,6 +5277,30 @@ return '#f1c40f'; // Default yellow }, + // Parse phase configuration into repeating labels array + parsePhaseLabels: function(phases) { + if (!phases) return []; + var p = phases.toUpperCase(); + + // Common configurations + if (p === '3P' || p === 'L1L2L3') return ['L1', 'L2', 'L3']; + if (p === '3P+N' || p === '3PN') return ['L1', 'L2', 'L3', 'N']; + if (p === '3P+N+PE' || p === '3PNPE') return ['L1', 'L2', 'L3', 'N', 'PE']; + if (p === 'L1N' || p === 'L1+N') return ['L1', 'N']; + if (p === 'L1') return ['L1']; + if (p === 'L2') return ['L2']; + if (p === 'L3') return ['L3']; + if (p === 'N') return ['N']; + if (p === 'PE') return ['PE']; + + // Try to split by + or comma + if (p.indexOf('+') !== -1) return p.split('+'); + if (p.indexOf(',') !== -1) return p.split(','); + + // Single phase/label + return [phases]; + }, + // Get connection color for a specific terminal (if connected) getTerminalConnectionColor: function(equipmentId, terminalId) { var eqId = String(equipmentId); @@ -5479,10 +5504,31 @@ } this.anlageId = anlageId; this.loadDisplaySettings(); + this.loadBusbarTypes(); this.bindEvents(); this.loadData(); }, + // Load busbar types from database + loadBusbarTypes: function() { + var self = this; + $.ajax({ + url: baseUrl + '/custom/kundenkarte/ajax/busbar_types.php', + data: { action: 'list', system_id: 0 }, // 0 = Alle Systeme + dataType: 'json', + async: false, // Synchron laden damit Typen sofort verfügbar sind + success: function(response) { + if (response.success && response.types) { + self.busbarTypes = response.types; + self.log('Loaded ' + self.busbarTypes.length + ' busbar types'); + } + }, + error: function() { + console.warn('Could not load busbar types'); + } + }); + }, + bindEvents: function() { var self = this; @@ -6378,19 +6424,34 @@ var totalTE = carrier ? (parseFloat(carrier.total_te) || 12) : 12; var html = '
'; - html += '
'; + html += '
'; html += '

Sammelschiene bearbeiten

'; - // Phase type selection - html += '
'; - html += ''; + + var currentTypeId = conn.fk_busbar_type; + if (this.busbarTypes && this.busbarTypes.length > 0) { + this.busbarTypes.forEach(function(type) { + var selected = (String(type.id) === String(currentTypeId)) ? ' selected' : ''; + html += ''; + } html += '
'; // Start TE @@ -6413,9 +6474,9 @@ html += '
'; html += '
'; - // Color - html += '
'; - html += '
'; + // Color preview (read-only, set from type) + html += '
'; + html += '
'; html += '
'; html += ''; @@ -6424,31 +6485,63 @@ $('body').append(html); + // Update color preview based on type selection + function updateFromType() { + var $selected = $('.dialog-busbar-type option:selected'); + var color = $selected.data('color') || '#e74c3c'; + var colors = $selected.data('colors') || color; + + // Show multi-color preview if multiple colors + var colorArr = colors.split(','); + if (colorArr.length > 1) { + var gradient = 'linear-gradient(to right, ' + colorArr.join(', ') + ')'; + $('.dialog-busbar-color-preview').css('background', gradient); + } else { + $('.dialog-busbar-color-preview').css('background', color); + } + } + + $('.dialog-busbar-type').on('change', updateFromType); + updateFromType(); // Initial update + $('.dialog-cancel, .schematic-dialog-overlay').on('click', function() { $('.schematic-dialog, .schematic-dialog-overlay').remove(); }); $('.dialog-save').on('click', function() { - var newPhases = $('.dialog-busbar-phases').val(); + var $selected = $('.dialog-busbar-type option:selected'); + var typeId = $('.dialog-busbar-type').val(); + var phases = $selected.data('phases') || 'L1'; + var color = $selected.data('colors') || $selected.data('color') || '#e74c3c'; var startTE = parseInt($('.dialog-busbar-start').val()) || 1; var endTE = parseInt($('.dialog-busbar-end').val()) || totalTE; var newPosY = parseInt($('.dialog-busbar-position').val()) || 0; var excludedTE = $('.dialog-busbar-excluded').val() || ''; - var color = $('.dialog-busbar-color').val(); - self.updateBusbar(connectionId, newPhases, startTE, endTE, newPosY, color, excludedTE); + self.updateBusbar(connectionId, typeId, phases, startTE, endTE, newPosY, color, excludedTE); $('.schematic-dialog, .schematic-dialog-overlay').remove(); }); }, - updateBusbar: function(connectionId, phases, startTE, endTE, positionY, color, excludedTE) { + updateBusbar: function(connectionId, typeId, phases, startTE, endTE, positionY, color, excludedTE) { var self = this; + + // Get phases_config from busbar type if available + var phasesConfig = null; + if (typeId && this.busbarTypes) { + var busbarType = this.busbarTypes.find(function(t) { return String(t.id) === String(typeId); }); + if (busbarType && busbarType.phases_config) { + phasesConfig = busbarType.phases_config; + } + } + $.ajax({ url: baseUrl + '/custom/kundenkarte/ajax/equipment_connection.php', method: 'POST', data: { action: 'update', connection_id: connectionId, + fk_busbar_type: typeId || 0, rail_start_te: startTE, rail_end_te: endTE, rail_phases: phases, @@ -6465,6 +6558,7 @@ // Update local data var conn = self.connections.find(function(c) { return String(c.id) === String(connectionId); }); if (conn) { + conn.fk_busbar_type = typeId; conn.rail_start_te = startTE; conn.rail_end_te = endTE; conn.rail_phases = phases; @@ -6472,6 +6566,7 @@ conn.color = color; conn.excluded_te = excludedTE; conn.connection_type = phases; + conn.phases_config = phasesConfig; } self.render(); } else { @@ -7383,23 +7478,15 @@ excludedTEs = conn.excluded_te.split(',').map(function(t) { return parseInt(t.trim()); }).filter(function(t) { return !isNaN(t); }); } - // Determine phase labels based on rail_phases + // Determine phase labels - use phases_config from busbar type if available var phases = conn.rail_phases || conn.connection_type || ''; - var phaseLabels = []; - if (phases === 'L1L2L3') { - phaseLabels = ['L1', 'L2', 'L3']; - } else if (phases === 'L1') { - phaseLabels = ['L1']; - } else if (phases === 'L2') { - phaseLabels = ['L2']; - } else if (phases === 'L3') { - phaseLabels = ['L3']; - } else if (phases === 'N') { - phaseLabels = ['N']; - } else if (phases === 'PE') { - phaseLabels = ['PE']; - } else if (phases) { - phaseLabels = [phases]; + var phaseLabels; + if (conn.phases_config && Array.isArray(conn.phases_config) && conn.phases_config.length > 0) { + // Use configured phase labels from busbar type admin settings + phaseLabels = conn.phases_config; + } else { + // Fall back to parsing phases string + phaseLabels = self.parsePhaseLabels(phases); } // Draw taps per TE (not per block) - each TE gets its own connection point @@ -7445,13 +7532,15 @@ } } - // Main phase label in the CENTER of the busbar + // Badge with phase name at the END of the busbar if (phases) { - var labelX = startX + width / 2; - var labelY = busbarY + busbarHeight / 2 + 4; - html += ''; + html += ' 0) { + this.busbarTypes.forEach(function(type, idx) { + var selected = idx === 0 ? ' selected' : ''; + html += '
'; - // Position (above/below) + // Position (above/below) - pre-selected from type html += '
'; html += '
'; // Excluded TEs html += '
'; html += '
'; - // Color - html += '
'; - html += '
'; + // Color preview (read-only, set from type) + html += '
'; + html += '
'; html += '
'; html += ''; - html += ''; + html += ''; html += '
'; $('body').append(html); - // Auto-set color based on phase selection - $('.dialog-busbar-phases').on('change', function() { - var phase = $(this).val(); - var color = '#e74c3c'; // default red - if (phase === 'L1') color = '#8B4513'; // brown - else if (phase === 'L2') color = '#000000'; // black - else if (phase === 'L3') color = '#808080'; // gray - else if (phase === 'N') color = '#3498db'; // blue - else if (phase === 'PE') color = '#f1c40f'; // yellow-green - else if (phase === 'L1L2L3') color = '#e74c3c'; // red for 3-phase - $('.dialog-busbar-color').val(color); - }); + // Update color and position based on type selection + function updateFromType() { + var $selected = $('.dialog-busbar-type option:selected'); + var color = $selected.data('color') || '#e74c3c'; + var colors = $selected.data('colors') || color; + var position = $selected.data('position') || 'below'; + + // Show multi-color preview if multiple colors + var colorArr = colors.split(','); + if (colorArr.length > 1) { + var gradient = 'linear-gradient(to right, ' + colorArr.join(', ') + ')'; + $('.dialog-busbar-color-preview').css('background', gradient); + } else { + $('.dialog-busbar-color-preview').css('background', color); + } + + $('.dialog-busbar-position').val(position); + } + + $('.dialog-busbar-type').on('change', updateFromType); + updateFromType(); // Initial update $('.dialog-cancel, .schematic-dialog-overlay').on('click', function() { $('.schematic-dialog, .schematic-dialog-overlay').remove(); }); $('.dialog-save').on('click', function() { - var phases = $('.dialog-busbar-phases').val(); + var $selected = $('.dialog-busbar-type option:selected'); + var typeId = $('.dialog-busbar-type').val(); + var phases = $selected.data('phases') || 'L1'; + var color = $selected.data('colors') || $selected.data('color') || '#e74c3c'; + var numLines = $selected.data('num-lines') || 1; var startTE = parseInt($('.dialog-busbar-start').val()) || 1; var endTE = parseInt($('.dialog-busbar-end').val()) || totalTE; - var positionY = parseInt($('.dialog-busbar-position').val()) || 0; - var color = $('.dialog-busbar-color').val(); + var position = $('.dialog-busbar-position').val(); var excludedTE = $('.dialog-busbar-excluded').val() || ''; - self.createBusbar(carrierId, phases, startTE, endTE, positionY, color, excludedTE); + console.log('=== BUSBAR CREATE ===', {carrierId: carrierId, typeId: typeId, phases: phases}); + self.createBusbar(carrierId, phases, startTE, endTE, position, color, excludedTE, numLines, typeId); $('.schematic-dialog, .schematic-dialog-overlay').remove(); }); }, - createBusbar: function(carrierId, phases, startTE, endTE, positionY, color, excludedTE) { + createBusbar: function(carrierId, phases, startTE, endTE, position, color, excludedTE, numLines, typeId) { var self = this; + console.log('createBusbar called:', carrierId, phases, startTE, endTE); + // Convert position string to number for backend (0=above, 1=below) + var positionY = (position === 'below') ? 1 : 0; + numLines = numLines || 1; + $.ajax({ url: baseUrl + '/custom/kundenkarte/ajax/equipment_connection.php', method: 'POST', @@ -8738,6 +8864,8 @@ color: color, excluded_te: excludedTE, connection_type: phases, + num_lines: numLines, + fk_busbar_type: typeId || 0, token: $('input[name="token"]').val() }, dataType: 'json', @@ -8755,12 +8883,18 @@ position_y: positionY, color: color, excluded_te: excludedTE, - connection_type: phases + connection_type: phases, + num_lines: numLines }); self.render(); } else { - self.showMessage(response.error || 'Fehler', 'error'); + self.showMessage(response.error || 'Fehler beim Erstellen', 'error'); + console.error('Busbar create error:', response); } + }, + error: function(xhr, status, error) { + self.showMessage('AJAX Fehler: ' + error, 'error'); + console.error('Busbar AJAX error:', status, error, xhr.responseText); } }); }, diff --git a/js/pwa.js b/js/pwa.js index 1083fd1..f173ed6 100644 --- a/js/pwa.js +++ b/js/pwa.js @@ -2396,7 +2396,7 @@ } // Phasen-Optionen wie auf der Website - const INPUT_PHASES = ['L1', 'L2', 'L3', '3P', '3P+N', 'PE']; + const INPUT_PHASES = ['L1', 'L2', 'L3', 'N', 'PE']; const OUTPUT_PHASES = ['LN', 'N', '3P+N', 'PE', 'DATA']; /** @@ -2574,7 +2574,7 @@
- Anschlusspunkt (L1/L2/L3) + Anschlusspunkt (Einspeisung)
diff --git a/sw.js b/sw.js index e7999bf..63b9e88 100644 --- a/sw.js +++ b/sw.js @@ -3,8 +3,8 @@ * Offline-First für Schaltschrank-Dokumentation */ -const CACHE_NAME = 'kundenkarte-pwa-v11.1'; -const OFFLINE_CACHE = 'kundenkarte-offline-v11.1'; +const CACHE_NAME = 'kundenkarte-pwa-v11.6'; +const OFFLINE_CACHE = 'kundenkarte-offline-v11.6'; // Statische Assets die immer gecached werden (ohne Query-String) const STATIC_ASSETS = [