diff --git a/Layout/default/Pop/Detail.php b/Layout/default/Pop/Detail.php index aa661967a..e4a85413e 100644 --- a/Layout/default/Pop/Detail.php +++ b/Layout/default/Pop/Detail.php @@ -70,6 +70,15 @@ if (!empty(trim($pops->vlan_ipv6))) Kategorie category]['name']." (".$categoryArray[$pops->category]['comment'].")" ?> + + Adresse + + number . ", " . $pops->zip . " " . $pops->city) ?>" + target="_blank">street ?> number ?>, zip ?> city ?> + + Standort diff --git a/Layout/default/Pop/Form.php b/Layout/default/Pop/Form.php index 213563879..b3e71457d 100644 --- a/Layout/default/Pop/Form.php +++ b/Layout/default/Pop/Form.php @@ -112,11 +112,60 @@ if (isset($_GET['returnto']) && $_GET['returnto'] == "pop-detail") {
-
+
+ +
+
+
+ PLZ +
+ +
+
+
+
+
+ Ort +
+ +
+
+
+ +
+ + + +street ?> + + +
+
+
+ Straße +
+ +
+
+
+
+
+ Nr. +
+ +
+
+
+ diff --git a/application/Pop/PopController.php b/application/Pop/PopController.php index e03af32a7..c9c58c4b5 100644 --- a/application/Pop/PopController.php +++ b/application/Pop/PopController.php @@ -52,6 +52,10 @@ class PopController extends mfBaseController "category" => $pop->category ?: 99, "networkArea" => $pop->networks, "location" => $pop->location, + "zip" => $pop->zip, + "city" => $pop->city, + "street" => $pop->street, + "number" => $pop->number, "state" => $pop->state, "folder_link" => $pop->folder_link, "doku_date" => $pop->doku_date, @@ -142,6 +146,7 @@ class PopController extends mfBaseController { $network_id = 90; $this->layout()->set("network_id", $network_id); + $this->layout()->set("networks", NetworkModel::getAll()); $this->layout()->set("categories", $this->getMapCategories()); $this->layout()->setTemplate("Pop/Map"); } @@ -1295,6 +1300,10 @@ class PopController extends mfBaseController $data['gps_lat'] = ($r->gps_lat) ? $r->gps_lat : null; $data['gps_long'] = ($r->gps_long) ? $r->gps_long : null; $data['location'] = $r->location; + $data['zip'] = $r->zip; + $data['city'] = $r->city; + $data['street'] = $r->street; + $data['number'] = $r->number; $data['vlan_public'] = ($r->vlan_public) ? $r->vlan_public : null; $data['vlan_nat'] = ($r->vlan_nat) ? $r->vlan_nat : null; $data['vlan_ipv6'] = ($r->vlan_ipv6) ? $r->vlan_ipv6 : null; @@ -1561,7 +1570,7 @@ class PopController extends mfBaseController $db = FronkDB::singleton(); $pops = []; $popQuery = " - SELECT DISTINCT p.id, p.name, p.gps_lat, p.gps_long + SELECT DISTINCT p.id, p.name, p.gps_lat, p.gps_long, p.zip, p.city, p.street, p.number FROM Pop p INNER JOIN PopNetwork pn ON p.id = pn.pop_id INNER JOIN Network n ON pn.network_id = n.id @@ -1577,6 +1586,10 @@ class PopController extends mfBaseController 'name' => $popData->name, 'lat' => floatval($popData->gps_lat), 'lng' => floatval($popData->gps_long), + 'zip' => $popData->zip, + 'city' => $popData->city, + 'street' => $popData->street, + 'number' => $popData->number, 'type' => 'pop' ]; } @@ -1769,9 +1782,62 @@ class PopController extends mfBaseController } } + $pipes = []; + $pipeQuery = " + SELECT DISTINCT p.id, p.description, p.coordinates, p.type_tmp, p.coat_color, p.layer, p.status, p.state + FROM FiberPlanPipe p + INNER JOIN FiberPlanPipeEndpoint pe ON p.id = pe.fiberPlanPipe_id + LEFT JOIN FiberPlanDispatcher d ON pe.fiberPlanDispatcher_id = d.id + LEFT JOIN FiberPlanAddress a ON pe.fiberPlanAddress_id = a.id + LEFT JOIN PopNetwork pn ON pe.pop_id = pn.pop_id + WHERE + (d.network_id = $network_id) OR + (a.network_id = $network_id) OR + (pn.network_id = $network_id) + "; + + $pipeRes = $db->query($pipeQuery); + if ($db->num_rows($pipeRes)) { + while ($pipeData = $db->fetch_object($pipeRes)) { + if (!empty($pipeData->coordinates)) { + $coords_array = json_decode($pipeData->coordinates, true); + if (is_array($coords_array) && count($coords_array) > 0) { + $convertedCoords = []; + foreach ($coords_array as $coord) { + if (isset($coord['gps_lat']) && isset($coord['gps_long'])) { + $convertedCoords[] = [ + 'lat' => floatval($coord['gps_lat']), + 'lng' => floatval($coord['gps_long']) + ]; + } elseif (isset($coord['lat']) && isset($coord['lng'])) { + $convertedCoords[] = [ + 'lat' => floatval($coord['lat']), + 'lng' => floatval($coord['lng']) + ]; + } + } + + if (count($convertedCoords) >= 2) { + $pipes[] = [ + 'id' => intval($pipeData->id), + 'name' => $pipeData->description, + 'coordinates' => $convertedCoords, + 'type' => $pipeData->type_tmp, + 'color' => $pipeData->coat_color, + 'layer' => $pipeData->layer, + 'status' => $pipeData->status, + 'state' => $pipeData->state + ]; + } + } + } + } + } + return mfBaseController::returnJson(mfResponse::Ok([ 'pops' => $pops, 'cables' => $cables, + 'pipes' => $pipes, 'distributors' => $distributors, 'splices' => $splices, 'customerConnections' => $customerConnections diff --git a/application/Pop/PopModel.php b/application/Pop/PopModel.php index f6c15b14e..1ed53948b 100644 --- a/application/Pop/PopModel.php +++ b/application/Pop/PopModel.php @@ -8,6 +8,10 @@ class PopModel public $gps_lat = null; public $gps_long = null; public $location = null; + public $zip = null; + public $city = null; + public $street = null; + public $number = null; public $vlan_public = null; public $vlan_nat = null; public $vlan_ipv6 = null; diff --git a/db/migrations/20260220100000_pop_add_address_fields.php b/db/migrations/20260220100000_pop_add_address_fields.php new file mode 100644 index 000000000..76076cb71 --- /dev/null +++ b/db/migrations/20260220100000_pop_add_address_fields.php @@ -0,0 +1,36 @@ +table('Pop'); + if (!$table->hasColumn('zip')) { + $table->addColumn('zip', 'string', ['null' => true, 'limit' => 10, 'after' => 'location']); + } + if (!$table->hasColumn('city')) { + $table->addColumn('city', 'string', ['null' => true, 'limit' => 255, 'after' => 'zip']); + } + if (!$table->hasColumn('street')) { + $table->addColumn('street', 'string', ['null' => true, 'limit' => 255, 'after' => 'city']); + } + if (!$table->hasColumn('number')) { + $table->addColumn('number', 'string', ['null' => true, 'limit' => 20, 'after' => 'street']); + } + $table->update(); + } + + public function down(): void + { + $table = $this->table('Pop'); + $table->removeColumn('zip') + ->removeColumn('city') + ->removeColumn('street') + ->removeColumn('number') + ->update(); + } +} diff --git a/public/js/pages/Pop/PopMap.js b/public/js/pages/Pop/PopMap.js index 87f13abb4..d267f91b0 100644 --- a/public/js/pages/Pop/PopMap.js +++ b/public/js/pages/Pop/PopMap.js @@ -28,7 +28,12 @@ Vue.component('pop-map-modal', {
{{ pop.name }}
- {{ categories[pop.category || 99] }} | {{ pop.location }} + + + {{ categories[pop.category || 99] }} + @@ -257,11 +262,15 @@ Vue.component('pop-map-modal', { let categoryName = this.categories[category] || 'Unbekannt'; let stateText = this.states[pop.state] || pop.state || '-'; + let addressHtml = (pop.street || pop.city) + ? `
Adresse: ${pop.street || ''} ${pop.number || ''}, ${pop.zip || ''} ${pop.city || ''}
` + : ''; const popupContent = `
${pop.name}

+ ${addressHtml}
Kategorie: ${categoryName}
Status: ${stateText}
Info: ${pop.location || '-'}
@@ -300,7 +309,10 @@ Vue.component('pop-map-modal', { this.filteredPops = this.allPops.filter(pop => pop.name.toLowerCase().includes(query) || - (pop.location && pop.location.toLowerCase().includes(query)) + (pop.location && pop.location.toLowerCase().includes(query)) || + (pop.street && pop.street.toLowerCase().includes(query)) || + (pop.city && pop.city.toLowerCase().includes(query)) || + (pop.zip && pop.zip.toLowerCase().includes(query)) ).slice(0, 10); this.showSuggestions = true; @@ -345,10 +357,20 @@ Vue.component('pop-map-modal', { this.showSuggestions = false; this.selectedIndex = -1; - let found = this.markers.find(m => m.popData.name.toLowerCase().includes(query)); + let found = this.markers.find(m => + m.popData.name.toLowerCase().includes(query) || + (m.popData.street && m.popData.street.toLowerCase().includes(query)) || + (m.popData.city && m.popData.city.toLowerCase().includes(query)) || + (m.popData.zip && m.popData.zip.toLowerCase().includes(query)) + ); if (!found) { - const hiddenPop = this.allPops.find(p => p.name.toLowerCase().includes(query)); + const hiddenPop = this.allPops.find(p => + p.name.toLowerCase().includes(query) || + (p.street && p.street.toLowerCase().includes(query)) || + (p.city && p.city.toLowerCase().includes(query)) || + (p.zip && p.zip.toLowerCase().includes(query)) + ); if (hiddenPop) { const category = hiddenPop.category || 99; if (!this.visibleCategories[category]) { diff --git a/public/js/pages/Pop/PopView.js b/public/js/pages/Pop/PopView.js index 49e765e7f..527aa77ca 100644 --- a/public/js/pages/Pop/PopView.js +++ b/public/js/pages/Pop/PopView.js @@ -20,6 +20,17 @@ Vue.component('Pop', { {{row.name}} + + @@ -64,12 +75,6 @@ Vue.component('Pop', { defaultPageSize: 25, headers: [ {text: 'Name', key: 'name', priority: 10}, - {text: 'Kategorie', key: 'category', class: 'text-center', priority: 4, filter: 'select', filterOptions: [ - {value: '1', text: 'Outdoor (Kasten/Schrank)'}, - {value: '2', text: 'Indoor (Keller Gebäude)'}, - {value: '3', text: 'Sender/Funk (Sendemast)'}, - {value: '4', text: 'Container (Garage, Container)'}, - {value: '99', text: 'Unbekannt'}]}, {text: 'Netzgebiet', key: 'networkArea', class: 'text-center', // TODO: fix autocomplete Filter // filter: 'autocomplete', @@ -78,7 +83,8 @@ Vue.component('Pop', { }, {text: 'Zutritt', key: 'location', class: 'text-center', priority: 1}, {text: 'Standort', key: 'gps', class: 'text-center', priority: 2}, - {text: 'Status', key: 'state', class: 'text-center', priority: 3, filter: 'select', filterOptions: [ + {text: 'Adresse', key: 'address', class: 'text-center', priority: 3}, + {text: 'Status', key: 'state', class: 'text-center', priority: 4, filter: 'select', filterOptions: [ {value: '1', text: 'Planung'}, {value: '2', text: 'Bauphase'}, {value: '3', text: 'Grobdoku'},