Merge branch 'spidev' into 'master'
Faserplanung See merge request fronk/thetool!1917
This commit is contained in:
+104
-271
@@ -1,274 +1,11 @@
|
||||
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); ?>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= $git_merge_ts ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<style>
|
||||
.card-border {
|
||||
|
||||
border-left: 1px solid #428bca;
|
||||
border-left-width: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.font-weight-500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-date-pill {
|
||||
margin: 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rack-he:hover {
|
||||
box-shadow: 2px 2px 5px 2px rgba(0, 0, 0, 0.31);
|
||||
}
|
||||
|
||||
.rack-color-lwl {
|
||||
background: rgb(159, 255, 96);
|
||||
background: linear-gradient(180deg, rgb(129 223 68) 0%, rgb(62 155 3) 100%);
|
||||
color: #000000;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.rack-color-device {
|
||||
background: rgb(182, 198, 240);
|
||||
background: linear-gradient(180deg, rgba(182, 198, 240, 1) 0%, rgb(131 158 255 / 82%) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.rack-color-infra {
|
||||
background: rgb(251 181 109);
|
||||
background: linear-gradient(180deg, rgb(247 184 118) 0%, rgb(255 149 40) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.rack-color-panel {
|
||||
background: rgb(150, 243, 222);
|
||||
background: linear-gradient(180deg, rgba(150, 243, 222, 1) 0%, rgba(87, 249, 212, 1) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.rack-color-blocked {
|
||||
background: rgb(255, 0, 0);
|
||||
background: linear-gradient(180deg, rgba(255, 0, 0, 1) 0%, rgba(196, 0, 0, 1) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.rack-color-rpanel {
|
||||
background: rgb(88, 201, 240);
|
||||
background: linear-gradient(180deg, rgba(88, 201, 240, 1) 0%, rgba(64, 188, 231, 1) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.user-select-none {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fa-edit {
|
||||
margin-right: 5px;
|
||||
margin-top: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rack-name {
|
||||
|
||||
}
|
||||
|
||||
.move-handle {
|
||||
cursor: grab;
|
||||
margin-left: 5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.move-handle:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.border-right {
|
||||
border-right-color: #dee2e6 !important;
|
||||
}
|
||||
|
||||
.form-control:disabled, .form-control[readonly] {
|
||||
background-color: #d7d7d7;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.switch-rack-side {
|
||||
margin-right: 8px;
|
||||
margin-top: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cable-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: stretch;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cable-item {
|
||||
border-right: 1px solid #797979;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
line-height: 1.1;
|
||||
color: #333;
|
||||
background-color: #e1ffdf;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding: 1px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cable-item .port-range, .cable-item .fiber-range {
|
||||
font-size: 12px;
|
||||
color: #040404;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cable-item:hover {
|
||||
background-color: #cfffc8;
|
||||
}
|
||||
|
||||
.cable-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.cable-free {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
width: 180px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.context-menu ul {
|
||||
list-style: none;
|
||||
padding: 5px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.context-menu ul li {
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.context-menu ul li:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.context-menu ul li i {
|
||||
margin-right: 10px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
#cable-context-menu {
|
||||
position: absolute; /* Popper setzt top/left */
|
||||
z-index: 20000;
|
||||
transform: none !important; /* falls doch mal ein transform reingeschummelt wird */
|
||||
}
|
||||
|
||||
.dropdown-menu[x-placement^=left], .dropdown-menu[x-placement^=right], .dropdown-menu[x-placement^=top] {
|
||||
top: unset;
|
||||
-webkit-animation: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
|
||||
.context-span {
|
||||
min-width: 25px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: .3rem 1.2rem;
|
||||
}
|
||||
|
||||
.w-10 {
|
||||
width: 10% !important;
|
||||
}
|
||||
|
||||
.cable-highlight {
|
||||
background-color: #e6ff00 !important;
|
||||
border: 2px solid #e0a800 !important;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* NEU: Animation für das "Aufblinken" */
|
||||
.cable-flash {
|
||||
/*animation: flash-animation 1s;*/
|
||||
}
|
||||
|
||||
@keyframes flash-animation {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
25% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
}
|
||||
75% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sorgt dafür, dass die Autocomplete-Vorschläge über anderen Elementen liegen */
|
||||
.ui-autocomplete {
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.module-highlight {
|
||||
/*box-shadow: inset 0 0 0 3px #007bff !important; !* Ein auffälliger, blauer Innen-Rahmen *!*/
|
||||
/*transition: box-shadow 0.3s ease-in-out;*/
|
||||
}
|
||||
|
||||
.rack-color-lwl-planned {
|
||||
background: rgb(255, 0, 0);
|
||||
background: linear-gradient(180deg, rgba(255, 0, 0, 1) 0%, rgba(196, 0, 0, 1) 100%);
|
||||
font-weight: 500;
|
||||
padding-top: 2px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.port-info {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
|
||||
}
|
||||
.cable-description
|
||||
{
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
color: #000000;
|
||||
white-space: normal;
|
||||
line-height: 1.2;
|
||||
font-weight: 400;
|
||||
}
|
||||
</style>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/print.min.css?<?= $git_merge_ts ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<!--<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css">-->
|
||||
<link href="<?= self::getResourcePath() ?>css/pages/Pop/Detail.css?<?= $git_merge_ts ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="page-title-box">
|
||||
@@ -692,6 +429,10 @@ if (!empty(trim($pops->vlan_ipv6)))
|
||||
class="rack-name"><i
|
||||
class="fa-regular fa-arrows-up-down-left-right move-handle float-left"></i><?= $poprack['rack']['name']; ?> <span
|
||||
class="rack-side-indicator font-weight-normal">- Vorderseite</span></span>
|
||||
<i class="fas fa-expand float-right mr-2 rack-fullscreen-btn"
|
||||
title="Vollbild & Drucken"
|
||||
style="cursor: pointer; margin-top: 2px;"
|
||||
data-rackid="<?= $poprack['rack']['id']; ?>"></i>
|
||||
<i class="fas fa-sync-alt float-right switch-rack-side"
|
||||
title="Seite wechseln"></i>
|
||||
|
||||
@@ -779,7 +520,8 @@ if (!empty(trim($pops->vlan_ipv6)))
|
||||
<div class="col-lg-1"></div>
|
||||
<label class="col-lg-4 col-form-label" for="cable-description">Beschreibung</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea id="cable-description" name="cable-description" class="form-control" rows="3"></textarea>
|
||||
<textarea id="cable-description" name="cable-description" class="form-control"
|
||||
rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-danger text-center" role="alert" style="display: none"
|
||||
@@ -849,7 +591,8 @@ if (!empty(trim($pops->vlan_ipv6)))
|
||||
<div class="col-lg-1"></div>
|
||||
<label class="col-lg-4 col-form-label" for="cable-description">Beschreibung</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea id="edit-cable-description" name="cable-description" class="form-control" rows="3"></textarea>
|
||||
<textarea id="edit-cable-description" name="cable-description" class="form-control"
|
||||
rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-danger text-center" role="alert" style="display: none"
|
||||
@@ -864,6 +607,80 @@ if (!empty(trim($pops->vlan_ipv6)))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="fiberPlanCableModal" tabindex="-1" role="dialog" aria-labelledby="fiberPlanCableModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="fiberPlanCableModalLabel">
|
||||
<i class="fa fa-cable"></i> Kabel-Details
|
||||
<!-- <button class="btn btn-primary btn-sm ml-3"-->
|
||||
<!-- id="modal-edit-cable-btn"-->
|
||||
<!-- style="display: none;">-->
|
||||
<!-- <i class="fas fa-table"></i> Excel-Editor-->
|
||||
<!-- </button>-->
|
||||
</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="fiberPlanCableModalBody">
|
||||
<div class="text-center py-5">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-3">Lade Kabel-Informationen...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="excelEditorModal" tabindex="-1" role="dialog" style="display: none;">
|
||||
<div class="modal-dialog modal-fullscreen-custom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="fas fa-table"></i> Kabel bearbeiten: <span id="cable-name"></span>
|
||||
</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body p-0 d-flex flex-column" style="flex: 1; overflow: hidden;">
|
||||
<div id="handsontable-container" style="flex: 1; width: 100%; overflow: hidden;"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Abbrechen
|
||||
</button>
|
||||
<button type="button" class="btn btn-success" id="save-excel-data">
|
||||
<i class="fas fa-save"></i> Speichern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="customRackOverlay">
|
||||
<div class="overlay-header">
|
||||
<h3 id="overlayTitle">Rack Detail</h3>
|
||||
<div>
|
||||
<button class="btn btn-info mr-2" onclick="printRackOverlay('landscape');" title="Querformat drucken">
|
||||
<i class="fas fa-print"></i> <i class="fas fa-arrows-alt-h"></i> Quer
|
||||
</button>
|
||||
|
||||
<button class="btn btn-info mr-2" onclick="printRackOverlay('portrait');" title="Hochformat drucken">
|
||||
<i class="fas fa-print"></i> <i class="fas fa-arrows-alt-v"></i> Hoch
|
||||
</button>
|
||||
|
||||
<button class="btn btn-secondary" onclick="$('#customRackOverlay').fadeOut(); $('body').css('overflow', '');">
|
||||
<i class="fas fa-times"></i> Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="overlayContent" class="d-flex justify-content-center overlayContent">
|
||||
</div>
|
||||
</div>
|
||||
<div id="cable-context-menu" class="dropdown-menu" style="display:none;">
|
||||
<a class="dropdown-item" href="#" data-action="view"><span class="context-span"><i
|
||||
class="fas fa-eye fa-fw"></i></span> Ansehen</a>
|
||||
@@ -889,10 +706,26 @@ if (!empty(trim($pops->vlan_ipv6)))
|
||||
let linkAddCable = "<?= self::getUrl("Poprackmodulecable", "api", ['do' => 'addCable']) ?>";
|
||||
let linkRemoveCable = "<?= self::getUrl("Poprackmodulecable", "api", ['do' => 'removeCable']) ?>";
|
||||
let linkUpdateCable = "<?= self::getUrl("Poprackmodulecable", "api", ['do' => 'updateCable']) ?>";
|
||||
|
||||
let linkGetCableDetails = "<?= self::getUrl('Pop', 'api', ['do' => 'getCableDetails']) ?>";
|
||||
let linkGetFiberPath = "<?= self::getUrl('Pop', 'api', ['do' => 'getFiberPath']) ?>";
|
||||
let linkGetCableFibersForEdit = "<?php echo mfBaseController::getUrl('Pop', 'api', array('do' => 'getCableFibersForEdit')); ?>";
|
||||
let linkSaveCableFibers = "<?php echo mfBaseController::getUrl('Pop', 'api', array('do' => 'saveCableFibers')); ?>";
|
||||
L.MakiMarkers.accessToken = '<?=TT_MAPBOX_TILE_API_TOKEN?>';
|
||||
var allCables = <?php echo $cables_json ?? '[]'; ?>;
|
||||
var popNetworkIds = <?php echo $popnetwork_ids ?? '[]'; ?>;
|
||||
$(function () {
|
||||
$('[data-toggle="popover"]').popover('dispose');
|
||||
$('[data-toggle="popover"]').popover();
|
||||
});
|
||||
</script>
|
||||
<!--<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>-->
|
||||
<script type="text/javascript" src="<?= self::getResourcePath() ?>assets/js/print.min.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript" src="<?= self::getResourcePath() ?>js/pages/pop/detail.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript" src="<?= self::getResourcePath() ?>js/pages/pop/fiber.js?<?= $git_merge_ts ?>"></script>
|
||||
<!--<script type="text/javascript"-->
|
||||
<!-- src="--><?php //= self::getResourcePath() ?><!--js/pages/pop/fibertable.js?--><?php //= $git_merge_ts ?><!--"></script>-->
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/datatables-std.js?<?= $git_merge_ts ?>"></script>
|
||||
|
||||
|
||||
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>
|
||||
|
||||
@@ -54,25 +54,53 @@ for ($i = 1; $i <= $rack_he; $i++) : ?>
|
||||
}
|
||||
$portCount = $cable['port_end'] - $cable['port_start'] + 1;
|
||||
$cableWidth = ($portCount / $slots['ports']) * 100;
|
||||
$cableTitle = htmlspecialchars($cable['cable_name'] . ' (Ports ' . $cable['port_start'] . '-' . $cable['port_end'] . ')', ENT_QUOTES);
|
||||
if (!empty($cable['description'])) {
|
||||
$cableTitle .= ' | ' . htmlspecialchars($cable['description'], ENT_QUOTES);
|
||||
|
||||
$popTitle = htmlspecialchars($cable['cable_name'], ENT_QUOTES);
|
||||
$popContent = '<strong>Ports:</strong> ' . $cable['port_start'] . '-' . $cable['port_end'];
|
||||
if (!empty($cable['fiber_start'])) {
|
||||
$popContent .= '<br><strong>Fasern:</strong> ' . $cable['fiber_start'] . '-' . $cable['fiber_end'];
|
||||
}
|
||||
$cellContent .= '<div class="cable-item" title="' . $cableTitle . '" style="width: ' . $cableWidth . '%;" data-cable-id="' . $cable['id'] . '"
|
||||
if (!empty($cable['description'])) {
|
||||
$popContent .= '<br><div class="mt-1 text-muted border-top pt-1 small"><em>' . htmlspecialchars($cable['description'], ENT_QUOTES) . '</em></div>';
|
||||
}
|
||||
|
||||
$narrowClass = ($cableWidth < 12) ? 'narrow' : '';
|
||||
$cellContent .= '<div class="cable-item ' . $narrowClass . '"
|
||||
data-toggle="popover"
|
||||
data-trigger="hover"
|
||||
data-html="true"
|
||||
data-placement="top"
|
||||
data-container="body"
|
||||
title="' . $popTitle . '"
|
||||
data-content="' . htmlspecialchars($popContent, ENT_QUOTES) . '"
|
||||
style="width: ' . $cableWidth . '%;"
|
||||
data-cable-id="' . $cable['id'] . '"
|
||||
data-cable-name="' . htmlspecialchars($cable['cable_name'], ENT_QUOTES) . '"
|
||||
data-port-start="' . $cable['port_start'] . '"
|
||||
data-port-end="' . $cable['port_end'] . '"
|
||||
data-fiber-start="' . ($cable['fiber_start'] ?? '') . '"
|
||||
data-fiber-end="' . ($cable['fiber_end'] ?? '') . '"
|
||||
data-description="' . htmlspecialchars($cable['description'] ?? '', ENT_QUOTES) . '">';
|
||||
$cellContent .= '<span><b>' . $cable['cable_name'] . "</b></span>";
|
||||
|
||||
$fontSize = ($cableWidth < 10) ? '10px' : 'inherit';
|
||||
$cellContent .= '<span style="font-size:'.$fontSize.'; overflow:hidden; text-overflow:ellipsis; max-width:100%; white-space:nowrap;"><b>' . $cable['cable_name'] . "</b></span>";
|
||||
if (!empty($cable['description'])) {
|
||||
$cellContent .= '<span class="cable-description" >' . htmlspecialchars($cable['description'], ENT_QUOTES) . '</span>';
|
||||
$descVisibilityClass = ($cableWidth <= 20) ? 'hide-if-narrow' : '';
|
||||
$cellContent .= '<span class="cable-description ' . $descVisibilityClass . '" >' . htmlspecialchars($cable['description'], ENT_QUOTES) . '</span>';
|
||||
}
|
||||
$cellContent .= '<div class="port-ranges-container" style="display: flex; justify-content: center; width: 100%; font-size: 10px; gap: 8px;">';
|
||||
$cellContent .= '<tool class="port-range">P: ' . $cable['port_start'] . '-' . $cable['port_end'] . '</tool>';
|
||||
$rangesVisibilityClass = ($cableWidth <= 5) ? 'hide-if-narrow' : '';
|
||||
|
||||
$infoSize = '10px';
|
||||
$infoGap = '8px';
|
||||
if ($cableWidth < 8) { $infoSize = '8px'; $infoGap = '1px'; }
|
||||
elseif ($cableWidth < 15) { $infoSize = '9px'; $infoGap = '3px'; }
|
||||
|
||||
$toolStyle = 'font-size: ' . $infoSize . '; white-space: nowrap;';
|
||||
$cellContent .= '<div class="port-ranges-container ' . $rangesVisibilityClass . '" style="display: flex; justify-content: center; width: 100%; line-height: 1.1; gap: ' . $infoGap . ';">';
|
||||
$cellContent .= '<tool class="port-range" style="' . $toolStyle . '">P: ' . $cable['port_start'] . '-' . $cable['port_end'] . '</tool>';
|
||||
|
||||
if (!empty($cable['fiber_start'])) {
|
||||
$cellContent .= '<tool class="fiber-range">F: ' . $cable['fiber_start'] . '-' . $cable['fiber_end'] . "</tool>";
|
||||
$cellContent .= '<tool class="fiber-range" style="' . $toolStyle . '">F: ' . $cable['fiber_start'] . '-' . $cable['fiber_end'] . "</tool>";
|
||||
}
|
||||
$cellContent .= '</div>';
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ class FiberPlanCableModel
|
||||
private $address_id;
|
||||
private $network_id;
|
||||
private $comment;
|
||||
|
||||
private $parent_cable_id;
|
||||
private $is_branch_cable;
|
||||
private $branch_from_location;
|
||||
private $branch_to_location;
|
||||
private $coordinates;
|
||||
public static $fibersArray = array(1 => 4, 2 => 12, 3 => 24, 4 => 24, 5 => 48, 6 => 96, 7 => 144, 8 => 144, 9 => 192, 10 => 288);
|
||||
|
||||
public static function find($data)
|
||||
@@ -132,12 +136,26 @@ class FiberPlanCableModel
|
||||
private static function getSqlFilter($filter)
|
||||
{
|
||||
$where = "1=1 ";
|
||||
if (array_key_exists("description", $filter) && $filter['description']) {
|
||||
$description = $filter['description'];
|
||||
$where .= " AND description='$description'";
|
||||
}
|
||||
|
||||
//var_dump($filter);exit;
|
||||
if (array_key_exists("network_id", $filter)) {
|
||||
$networkid = $filter['network_id'];
|
||||
if (is_numeric($networkid)) {
|
||||
$where .= " AND network_id=$networkid";
|
||||
if (is_array($filter['network_id'])) {
|
||||
$ids = array_map('intval', $filter['network_id']);
|
||||
$ids = array_filter($ids, function($id) { return $id > 0; });
|
||||
if (!empty($ids)) {
|
||||
$idList = implode(',', $ids);
|
||||
$where .= " AND network_id IN ($idList)";
|
||||
}
|
||||
} else {
|
||||
$network_id = intval($filter['network_id']);
|
||||
if ($network_id > 0) {
|
||||
$where .= " AND network_id=$network_id";
|
||||
} elseif ($network_id === 0) {
|
||||
$where .= " AND (network_id IS NULL OR network_id=0)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +257,51 @@ INNER JOIN `Address` ON (`Address`.`id`=`Addresstype`.`address_id`)
|
||||
return $items;
|
||||
|
||||
}
|
||||
public static function getCableRoute($cable_id) {
|
||||
$route = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
// SQL-Abfrage mit object_type für Dispatcher
|
||||
$sql = "SELECT
|
||||
fcs.station_order,
|
||||
fcs.station_type,
|
||||
fcs.station_id,
|
||||
CASE
|
||||
WHEN fcs.station_type = 'pop' THEN p.name
|
||||
WHEN fcs.station_type = 'dispatcher' THEN d.description
|
||||
END as station_name,
|
||||
CASE
|
||||
WHEN fcs.station_type = 'pop' THEN p.gps_lat
|
||||
WHEN fcs.station_type = 'dispatcher' THEN d.gps_lat
|
||||
END as gps_lat,
|
||||
CASE
|
||||
WHEN fcs.station_type = 'pop' THEN p.gps_long
|
||||
WHEN fcs.station_type = 'dispatcher' THEN d.gps_long
|
||||
END as gps_long,
|
||||
d.object_type
|
||||
FROM FiberPlanCableStation fcs
|
||||
LEFT JOIN Pop p ON fcs.station_type = 'pop' AND fcs.station_id = p.id
|
||||
LEFT JOIN FiberPlanDispatcher d ON fcs.station_type = 'dispatcher' AND fcs.station_id = d.id
|
||||
WHERE fcs.cable_id = " . intval($cable_id) . "
|
||||
ORDER BY fcs.station_order ASC";
|
||||
|
||||
$res = $db->query($sql);
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_array($res)) {
|
||||
$route[] = [
|
||||
'order' => $data['station_order'],
|
||||
'type' => $data['station_type'],
|
||||
'id' => $data['station_id'],
|
||||
'name' => $data['station_name'],
|
||||
'gps_lat' => $data['gps_lat'],
|
||||
'gps_long' => $data['gps_long'],
|
||||
'object_type' => $data['object_type'] // Neu: object_type hinzugefügt
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
public static function generateEndpoint($endpoint, $destination, $html = 1)
|
||||
{
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
class FiberPlanFiber extends mfBaseModel
|
||||
{
|
||||
private $editor;
|
||||
private $creator;
|
||||
private $cable;
|
||||
private $branch_cable;
|
||||
private $splitter;
|
||||
|
||||
public function getProperty($name)
|
||||
{
|
||||
if ($this->$name == null) {
|
||||
|
||||
if (!$this->id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($name == "creator") {
|
||||
$this->creator = mfValuecache::singleton()->get("Worker-id-" . $this->create_by);
|
||||
if ($this->creator === null) {
|
||||
$this->creator = new User($this->create_by);
|
||||
if ($this->creator->id) {
|
||||
mfValuecache::singleton()->set("Worker-id-" . $this->create_by, $this->creator);
|
||||
}
|
||||
}
|
||||
return $this->creator;
|
||||
}
|
||||
|
||||
if ($name == "editor") {
|
||||
$this->editor = mfValuecache::singleton()->get("Worker-id-" . $this->edit_by);
|
||||
if ($this->editor === null) {
|
||||
$this->editor = new User($this->edit_by);
|
||||
if ($this->editor->id) {
|
||||
mfValuecache::singleton()->set("Worker-id-" . $this->edit_by, $this->editor);
|
||||
}
|
||||
}
|
||||
return $this->editor;
|
||||
}
|
||||
if ($name == "cable" && $this->cable_id) {
|
||||
$this->cable = mfValuecache::singleton()->get("FiberPlanCable-id-" . $this->cable_id);
|
||||
if (!$this->cable) {
|
||||
$this->cable = new FiberPlanCable($this->cable_id);
|
||||
if ($this->cable->id) {
|
||||
mfValuecache::singleton()->set("FiberPlanCable-id-" . $this->cable_id, $this->cable);
|
||||
}
|
||||
}
|
||||
return $this->cable;
|
||||
}
|
||||
if ($name == "branch_cable" && $this->branch_cable_nr) {
|
||||
$this->branch_cable = mfValuecache::singleton()->get("Cable-nr-" . $this->branch_cable_nr);
|
||||
if (!$this->branch_cable) {
|
||||
$cables = FiberPlanCableModel::search(['description' => $this->branch_cable_nr]);
|
||||
if (count($cables) > 0) {
|
||||
$this->branch_cable = $cables[0];
|
||||
mfValuecache::singleton()->set("Cable-nr-" . $this->branch_cable_nr, $this->branch_cable);
|
||||
}
|
||||
}
|
||||
return $this->branch_cable;
|
||||
}
|
||||
|
||||
$classname = ucfirst($name);
|
||||
$idfield = $name . "_id";
|
||||
$this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-" . $this->$idfield);
|
||||
if (!$this->$name) {
|
||||
$this->$name = new $classname($this->$idfield);
|
||||
}
|
||||
|
||||
if ($this->$name->id) {
|
||||
mfValuecache::singleton()->set("mfObjectmodel-$name-" . $this->$name->id, $this->$name);
|
||||
return $this->$name;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
public function isBranchCable()
|
||||
{
|
||||
return ($this->branch_type == "Abzweigkabel");
|
||||
}
|
||||
|
||||
public function isCustomerConnection()
|
||||
{
|
||||
return (!empty($this->home_id));
|
||||
}
|
||||
|
||||
public function getFullPath()
|
||||
{
|
||||
$path = [];
|
||||
$current = $this;
|
||||
|
||||
$path[] = [
|
||||
'cable' => $current->cable,
|
||||
'fiber' => $current,
|
||||
'type' => 'main'
|
||||
];
|
||||
|
||||
if ($current->isBranchCable() && $current->branch_cable) {
|
||||
$branch_fiber = FiberPlanFiberModel::findByFiberNr(
|
||||
$current->branch_cable->id,
|
||||
$current->branch_fiber_nr,
|
||||
$current->branch_bundle_nr,
|
||||
$current->branch_fiber_in_bundle
|
||||
);
|
||||
|
||||
if ($branch_fiber) {
|
||||
$path[] = [
|
||||
'cable' => $current->branch_cable,
|
||||
'fiber' => $branch_fiber,
|
||||
'type' => 'branch'
|
||||
];
|
||||
|
||||
if ($branch_fiber->isBranchCable()) {
|
||||
$sub_path = $branch_fiber->getFullPath();
|
||||
$path = array_merge($path, array_slice($sub_path, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
class FiberPlanFiberController extends mfBaseController
|
||||
{
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->needlogin = true;
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
$this->me = $me;
|
||||
$this->layout()->set("me", $me);
|
||||
|
||||
if (!$me->is(["Admin"])) {
|
||||
$this->redirect("Dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
protected function indexAction()
|
||||
{
|
||||
|
||||
$this->layout()->setTemplate("FiberPlanFiber/Index");
|
||||
$fiberplanfibers = FiberPlanFiberModel::getAll();
|
||||
$this->layout()->set("fiberplanfibers", $fiberplanfibers);
|
||||
|
||||
}
|
||||
|
||||
protected function addAction()
|
||||
{
|
||||
$cables=CableModel::getAll();
|
||||
$this->layout()->set("cables", $cables);
|
||||
|
||||
$this->layout()->setTemplate("FiberPlanFiber/Form");
|
||||
|
||||
}
|
||||
|
||||
protected function editAction()
|
||||
{
|
||||
$id = $this->request->id;
|
||||
|
||||
if (!is_numeric($id) || !$id) {
|
||||
$this->layout()->setFlash("Faser nicht gefunden", "error");
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
$fiberplanfibers = new FiberPlanFiber($id);
|
||||
if ($fiberplanfibers->id != $id) {
|
||||
$this->layout()->setFlash("Faser nicht gefunden", "error");
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
$this->layout()->set("fiberplanfibers", $fiberplanfibers);
|
||||
return $this->addAction();
|
||||
}
|
||||
protected function getCustomerLocationAction()
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$address = $this->request->address;
|
||||
$network_id = intval($this->request->network_id);
|
||||
|
||||
if (!$address) {
|
||||
echo json_encode(['success' => false, 'error' => 'Keine Adresse angegeben']);
|
||||
return;
|
||||
}
|
||||
|
||||
$db = FronkDB::singleton();
|
||||
$address_escaped = $db->escape($address);
|
||||
|
||||
$sql = "SELECT gps_lat, gps_long
|
||||
FROM FiberPlanAddress
|
||||
WHERE address LIKE '%$address_escaped%'
|
||||
AND network_id = $network_id
|
||||
AND gps_lat IS NOT NULL
|
||||
AND gps_long IS NOT NULL
|
||||
LIMIT 1";
|
||||
|
||||
$res = $db->query($sql);
|
||||
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'gps_lat' => $data->gps_lat,
|
||||
'gps_long' => $data->gps_long
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => 'Keine GPS-Koordinaten gefunden'
|
||||
]);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
protected function saveAction()
|
||||
{
|
||||
$r = $this->request;
|
||||
$id = $r->id;
|
||||
|
||||
if (is_numeric($id) && $id > 0) {
|
||||
$mode = "edit";
|
||||
$fiberplanfibers = new FiberPlanFiber($id);
|
||||
if (!$fiberplanfibers->id) {
|
||||
$this->layout()->setFlash("Fasern nicht gefunden", "error");
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
} else {
|
||||
$mode = "add";
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$data['cable_id'] = trim($r->cable_id);
|
||||
$data['sheet_range'] = trim($r->sheet_range);
|
||||
$data['connector_nr'] = trim($r->connector_nr);
|
||||
$data['fiber_nr_cable'] = trim($r->fiber_nr_cable);
|
||||
$data['bundle_nr'] = trim($r->bundle_nr);
|
||||
$data['fiber_nr_bundle'] = trim($r->fiber_nr_bundle);
|
||||
$data['fiber_color'] = trim($r->fiber_color);
|
||||
$data['branch_type'] = trim($r->branch_type);
|
||||
$data['branch_cable_nr'] = trim($r->branch_cable_nr);
|
||||
$data['branch_fiber_count'] = trim($r->branch_fiber_count);
|
||||
$data['branch_fiber_nr'] = trim($r->branch_fiber_nr);
|
||||
$data['branch_bundle_nr'] = trim($r->branch_bundle_nr);
|
||||
$data['branch_fiber_in_bundle'] = trim($r->branch_fiber_in_bundle);
|
||||
$data['branch_from_location'] = trim($r->branch_from_location);
|
||||
$data['branch_to_location'] = trim($r->branch_to_location);
|
||||
$data['branch_gis_id'] = trim($r->branch_gis_id);
|
||||
$data['address'] = trim($r->address);
|
||||
$data['name'] = trim($r->name);
|
||||
$data['home_id'] = trim($r->home_id);
|
||||
$data['location'] = trim($r->location);
|
||||
$data['rack_unit'] = trim($r->rack_unit);
|
||||
$data['termination_type'] = trim($r->termination_type);
|
||||
$data['customer_cable_type'] = trim($r->customer_cable_type);
|
||||
$data['customer_cable_fiber_nr'] = trim($r->customer_cable_fiber_nr);
|
||||
$data['customer_connector_type'] = trim($r->customer_connector_type);
|
||||
$data['customer_cable_spec'] = trim($r->customer_cable_spec);
|
||||
$data['customer_fiber_range'] = trim($r->customer_fiber_range);
|
||||
$data['splitter_location'] = trim($r->splitter_location);
|
||||
$data['splitter_factor'] = trim($r->splitter_factor);
|
||||
$data['uuid_qgis_kabel'] = trim($r->uuid_qgis_kabel);
|
||||
$data['status'] = trim($r->status);
|
||||
$data['comment'] = trim($r->comment);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if ($value === '') {
|
||||
$data[$key] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == "edit") {
|
||||
$fiberplanfibers->update($data);
|
||||
} else {
|
||||
$fiberplanfibers = FiberPlanFiberModel::create($data);
|
||||
}
|
||||
|
||||
$id = $fiberplanfibers->save();
|
||||
|
||||
if (!$id) {
|
||||
$this->layout()->setFlash("Faser konnte nicht angelegt werden", "error");
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
if ($mode == "edit") {
|
||||
$this->layout()->setFlash("Faser erfolgreich geändert", "success");
|
||||
} else if ($mode = "add") {
|
||||
$this->layout()->setFlash("Faser erfolgreich angelegt", "success");
|
||||
}
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
protected function deleteAction()
|
||||
{
|
||||
$id = $this->request->id;
|
||||
$fiberplanfibers = new FiberPlanFiber($id);
|
||||
if (!$fiberplanfibers->id || $fiberplanfibers->id != $id) {
|
||||
$this->layout()->setFlash("Faser nicht gefunden.", "error");
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
$fiberplanfibers->delete();
|
||||
$this->redirect("FiberPlanFiber");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
class FiberPlanFiberModel
|
||||
{
|
||||
private $cable_id;
|
||||
private $sheet_range;
|
||||
private $connector_nr;
|
||||
private $fiber_nr_cable;
|
||||
private $bundle_nr;
|
||||
private $fiber_nr_bundle;
|
||||
private $fiber_color;
|
||||
private $bundle_color;
|
||||
private $fiber_color_hex;
|
||||
private $bundle_color_hex;
|
||||
private $branch_bundle_color_hex;
|
||||
|
||||
private $branch_type;
|
||||
private $branch_cable_nr;
|
||||
private $branch_fiber_count;
|
||||
private $branch_fiber_nr;
|
||||
private $branch_bundle_nr;
|
||||
private $branch_fiber_in_bundle;
|
||||
private $branch_bundle_color;
|
||||
private $branch_from_location;
|
||||
private $branch_to_location;
|
||||
private $branch_gis_id;
|
||||
|
||||
private $address;
|
||||
private $name;
|
||||
private $home_id;
|
||||
private $location;
|
||||
private $rack_unit;
|
||||
private $termination_type;
|
||||
|
||||
private $customer_cable_type;
|
||||
private $customer_cable_fiber_nr;
|
||||
private $customer_connector_type;
|
||||
private $customer_cable_spec;
|
||||
private $customer_fiber_range;
|
||||
|
||||
private $splitter_location;
|
||||
private $splitter_factor;
|
||||
|
||||
private $uuid_qgis_kabel;
|
||||
private $status;
|
||||
private $comment;
|
||||
|
||||
|
||||
public static function find($data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static function create(array $data)
|
||||
{
|
||||
$model = new FiberPlanFiber();
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
if (property_exists(get_called_class(), $field)) {
|
||||
if (substr($field, 0, 5) == "vlan_" && !$value) {
|
||||
$model->$field = null;
|
||||
continue;
|
||||
}
|
||||
$model->$field = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$me = mfValuecache::singleton()->get("me");
|
||||
if (!$me) {
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
mfValuecache::singleton()->set("me", $me);
|
||||
}
|
||||
|
||||
if ($model->create_by === null) {
|
||||
$model->create_by = $me->id;
|
||||
}
|
||||
if ($model->edit_by === null) {
|
||||
$model->edit_by = $me->id;
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public static function getOne($id)
|
||||
{
|
||||
if (!is_numeric($id) || !$id) {
|
||||
throw new Exception("Invalid number", 400);
|
||||
}
|
||||
$item = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "id=$id LIMIT 1");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
$item = new FiberPlanFiber($data);
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
public static function getAll()
|
||||
{
|
||||
$items = [];
|
||||
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "1=1");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new FiberPlanFiber($data);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
|
||||
}
|
||||
|
||||
public static function getFirst()
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where ");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
$item = new FiberPlanFiber($data);
|
||||
if ($item->id) {
|
||||
return $item;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function search($filter)
|
||||
{
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new FiberPlanFiber($data);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
private static function getSqlFilter($filter)
|
||||
{
|
||||
$where = "1=1 ";
|
||||
$db = FronkDB::singleton();
|
||||
//var_dump($filter);exit;
|
||||
if (array_key_exists("cable_id", $filter)) {
|
||||
$cable_id = intval($filter['cable_id']);
|
||||
if ($cable_id > 0) {
|
||||
$where .= " AND cable_id=$cable_id";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("sheet_range", $filter)) {
|
||||
$sheet_range = $db->escape($filter['sheet_range']);
|
||||
if ($sheet_range) {
|
||||
$where .= " AND sheet_range='$sheet_range'";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("connector_nr", $filter)) {
|
||||
$connector_nr = $db->escape($filter['connector_nr']);
|
||||
if ($connector_nr) {
|
||||
$where .= " AND connector_nr='$connector_nr'";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("fiber_nr_cable", $filter)) {
|
||||
$fiber_nr_cable = $db->escape($filter['fiber_nr_cable']);
|
||||
if ($fiber_nr_cable) {
|
||||
$where .= " AND fiber_nr_cable='$fiber_nr_cable'";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("home_id", $filter)) {
|
||||
$home_id = $db->escape($filter['home_id']);
|
||||
if ($home_id) {
|
||||
$where .= " AND home_id='$home_id'";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("branch_type", $filter)) {
|
||||
$branch_type = $db->escape($filter['branch_type']);
|
||||
if ($branch_type) {
|
||||
$where .= " AND branch_type='$branch_type'";
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists("status", $filter)) {
|
||||
$status = $db->escape($filter['status']);
|
||||
if ($status) {
|
||||
$where .= " AND status='$status'";
|
||||
}
|
||||
}
|
||||
//var_dump($filter, $where);exit;
|
||||
return $where;
|
||||
}
|
||||
|
||||
public static function findByFiberNr($cable_id, $fiber_nr_cable)
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$cable_id = intval($cable_id);
|
||||
$fiber_nr_cable = $db->escape($fiber_nr_cable);
|
||||
|
||||
$where = "cable_id=$cable_id AND fiber_nr_cable='$fiber_nr_cable'";
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where LIMIT 1");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return new FiberPlanFiber($data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getByCableAndSheet($cable_id, $sheet_range = null)
|
||||
{
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = "cable_id=$cable_id";
|
||||
if ($sheet_range) {
|
||||
$sheet_range = $db->escape($sheet_range);
|
||||
$where .= " AND sheet_range='$sheet_range'";
|
||||
}
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where ORDER BY connector_nr ASC");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new FiberPlanFiber($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function getBranchFibers($cable_id)
|
||||
{
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "cable_id=$cable_id AND branch_type='Abzweigkabel'");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new FiberPlanFiber($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function getCustomerConnections($cable_id)
|
||||
{
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "cable_id=$cable_id AND home_id IS NOT NULL AND home_id != ''");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new FiberPlanFiber($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function findByPosition($cable_id, $sheet_range, $connector_nr)
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$cable_id = intval($cable_id);
|
||||
$sheet_range = $db->escape($sheet_range);
|
||||
$connector_nr = $db->escape($connector_nr);
|
||||
|
||||
$where = "cable_id=$cable_id AND sheet_range='$sheet_range' AND connector_nr='$connector_nr'";
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where LIMIT 1");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return new FiberPlanFiber($data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function findByBranch($cable_id, $sheet_range, $branch_cable_nr, $branch_fiber_nr)
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$cable_id = intval($cable_id);
|
||||
$sheet_range = $db->escape($sheet_range);
|
||||
$branch_cable_nr = $db->escape($branch_cable_nr);
|
||||
$branch_fiber_nr = $db->escape($branch_fiber_nr);
|
||||
|
||||
$where = "cable_id=$cable_id AND sheet_range='$sheet_range' AND branch_cable_nr='$branch_cable_nr' AND branch_fiber_nr='$branch_fiber_nr'";
|
||||
|
||||
$res = $db->select("FiberPlanFiber", "*", "$where LIMIT 1");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return new FiberPlanFiber($data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Vendored
+1
@@ -0,0 +1 @@
|
||||
.printModal{font-family:sans-serif;display:flex;text-align:center;font-weight:300;font-size:30px;left:0;top:0;position:absolute;color:#0460b5;width:100%;height:100%;background-color:hsla(0,0%,100%,.91)}.printClose{position:absolute;right:10px;top:10px}.printClose:before{content:"\00D7";font-family:Helvetica Neue,sans-serif;font-weight:100;line-height:1px;padding-top:.5em;display:block;font-size:2em;text-indent:1px;overflow:hidden;height:1.25em;width:1.25em;text-align:center;cursor:pointer}
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+208
-390
@@ -3,70 +3,68 @@ $(document).ready(function () {
|
||||
Sortable.create(sortracklist, {
|
||||
handle: '.move-handle',
|
||||
onEnd: function () {
|
||||
|
||||
var popid = $('#sortracklist').data('popid');
|
||||
var racksortids = [];
|
||||
|
||||
$('#sortracklist').find('th').each(function (index, value) {
|
||||
|
||||
racksortids.push($(this).data('rackid'));
|
||||
});
|
||||
$.post(linkSorTracklist + "&pop_id=" + popid, {
|
||||
racksortids: racksortids
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
|
||||
}
|
||||
}, "json");
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
$('#pop-rack-div').show();
|
||||
|
||||
$('#rackModal').on('show.bs.modal', function (event) {
|
||||
var thisclick = $(event.relatedTarget);
|
||||
var rackhe = thisclick.closest('table').find('th').data('rackhe');
|
||||
var rackid = thisclick.closest('table').find('th').data('rackid');
|
||||
var rackname = thisclick.closest('table').find('th').data('rackname');
|
||||
var minhe = 1;
|
||||
var modal = $(this);
|
||||
var edit = 0;
|
||||
modal.find('.alert').text('');
|
||||
modal.find('.alert').hide();
|
||||
if (rackid === undefined) {
|
||||
$('#rack-name').val('');
|
||||
$('#rack-he').val('');
|
||||
var popid = thisclick.data('popid');
|
||||
$('#rack-add').data('popid', popid);
|
||||
$('#rack-update').hide();
|
||||
$('#rack-remove').hide();
|
||||
$('#rack-add').show();
|
||||
} else {
|
||||
edit = 1;
|
||||
$('#rack-remove').hide();
|
||||
$('#rack-add').hide();
|
||||
$('#rack-update').show();
|
||||
$('#rack-he').val(rackhe);
|
||||
$('#rack-name').val(rackname);
|
||||
for (let i = 1; i <= rackhe; i++) {
|
||||
if (!thisclick.closest('table').find('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
minhe = i;
|
||||
}
|
||||
}
|
||||
if (minhe === 1) {
|
||||
var thisclick = $(event.relatedTarget);
|
||||
var rackhe = thisclick.closest('table').find('th').data('rackhe');
|
||||
var rackid = thisclick.closest('table').find('th').data('rackid');
|
||||
var rackname = thisclick.closest('table').find('th').data('rackname');
|
||||
var minhe = 1;
|
||||
var modal = $(this);
|
||||
var edit = 0;
|
||||
modal.find('.alert').text('');
|
||||
modal.find('.alert').hide();
|
||||
|
||||
$('#rack-remove').data('rackid', rackid);
|
||||
$('#rack-remove').show();
|
||||
if (rackid === undefined) {
|
||||
$('#rack-name').val('');
|
||||
$('#rack-he').val('');
|
||||
var popid = thisclick.data('popid');
|
||||
$('#rack-add').data('popid', popid);
|
||||
$('#rack-update').hide();
|
||||
$('#rack-remove').hide();
|
||||
$('#rack-add').show();
|
||||
} else {
|
||||
edit = 1;
|
||||
$('#rack-remove').hide();
|
||||
$('#rack-add').hide();
|
||||
$('#rack-update').show();
|
||||
$('#rack-he').val(rackhe);
|
||||
$('#rack-name').val(rackname);
|
||||
|
||||
for (let i = 1; i <= rackhe; i++) {
|
||||
if (!thisclick.closest('table').find('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
minhe = i;
|
||||
}
|
||||
$('#rack-update').data('rackid', rackid);
|
||||
$('#rack-update').data('rackminhe', minhe);
|
||||
}
|
||||
}
|
||||
)
|
||||
;
|
||||
$('#rackModuleModal').on('show.bs.modal', function (event) {
|
||||
|
||||
if (minhe === 1) {
|
||||
$('#rack-remove').data('rackid', rackid);
|
||||
$('#rack-remove').show();
|
||||
}
|
||||
|
||||
$('#rack-update').data('rackid', rackid);
|
||||
$('#rack-update').data('rackminhe', minhe);
|
||||
}
|
||||
});
|
||||
|
||||
$('#rackModuleModal').on('show.bs.modal', function (event) {
|
||||
trigger = $(event.relatedTarget);
|
||||
var destinationname = trigger.closest('table').find('th').text();
|
||||
var rackhe = trigger.closest('table').find('th').data('rackhe');
|
||||
@@ -74,8 +72,6 @@ $(document).ready(function () {
|
||||
modal.find('.modal-title').html('<span id="module-info">Modul (' + destinationname + ')</span>');
|
||||
modal.find('.alert').text('');
|
||||
modal.find('.alert').hide();
|
||||
$('#module-slot-div').hide();
|
||||
$('#module-position-div').hide();
|
||||
var options;
|
||||
var selected;
|
||||
var hemaxcount = 1;
|
||||
@@ -84,6 +80,7 @@ $(document).ready(function () {
|
||||
var side = trigger.closest('tbody').data('side');
|
||||
$('#module-type option').prop('disabled', false);
|
||||
var parent = trigger.closest('tr');
|
||||
|
||||
if (trigger.closest('tr').find('td').eq(1).html() === undefined) {
|
||||
edit = 1;
|
||||
parent = trigger.closest('tr').prev();
|
||||
@@ -95,6 +92,7 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parent.find('td').eq(1).data('id') || parent.find('td').eq(2).data('id') || parent.find('td').eq(3).data('id') || parent.find('td').eq(4).data('id')) {
|
||||
var counttd = parent.find('td').length - 1;
|
||||
var newmodule = false;
|
||||
@@ -118,10 +116,8 @@ $(document).ready(function () {
|
||||
$('#module-slot').html(options);
|
||||
$('#module-position').html(options);
|
||||
$('#module-slot-div').show();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
} else {
|
||||
$('#module-slot-div').hide();
|
||||
}
|
||||
|
||||
$('#module-width').attr('disabled', 'disabled');
|
||||
@@ -138,18 +134,20 @@ $(document).ready(function () {
|
||||
$('#module-update').show();
|
||||
$('#module-add').hide();
|
||||
|
||||
|
||||
$('#module-type').val(parent.find('td').eq(1).data('type')).change();
|
||||
|
||||
if ($('#module-type').val() == "1") {
|
||||
$('#module-device-id').hide();
|
||||
$('#module-device-text').text(parent.find('td').eq(1).data('name'));
|
||||
$('#module-device-text').show();
|
||||
$('#module-type option').prop('disabled', true);
|
||||
}
|
||||
|
||||
if (parent.find('td').eq(1).data('ports') != "") {
|
||||
$('#module-ports').val(parent.find('td').eq(1).data('ports')).change();
|
||||
$('#module-plug').val(parent.find('td').eq(1).data('plug'));
|
||||
}
|
||||
|
||||
$('#module-name').val(parent.find('td').eq(1).data('name'));
|
||||
const status = parent.find('td').eq(1).data('status');
|
||||
$('#module-type').val(parent.find('td').eq(1).data('type')).change();
|
||||
@@ -157,7 +155,6 @@ $(document).ready(function () {
|
||||
|
||||
$('#module-type option[value="1"]').prop('disabled', true);
|
||||
|
||||
|
||||
$('#module-remove').data('moduleid', parent.find('td').eq(1).data('id'));
|
||||
$('#module-update').data('moduleid', parent.find('td').eq(1).data('id'));
|
||||
} else {
|
||||
@@ -184,29 +181,37 @@ $(document).ready(function () {
|
||||
$('#module-remove').hide();
|
||||
$('#module-update').hide();
|
||||
$('#module-add').show();
|
||||
|
||||
for (let i = 1; i <= rackhe; i++) {
|
||||
if (i == trigger.data('he')) {
|
||||
selected = 'selected="selected"';
|
||||
} else {
|
||||
selected = '';
|
||||
}
|
||||
|
||||
if (trigger.closest('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
options = options + '<option ' + selected + ' value="' + i + '">' + i + '</option>';
|
||||
}
|
||||
|
||||
if (hemaxcountactive == 1 && i > trigger.data('he') && !trigger.closest('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
hemaxcountactive = 0;
|
||||
}
|
||||
|
||||
if (hemaxcountactive == 1 && i > trigger.data('he') && trigger.closest('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
hemaxcount++;
|
||||
}
|
||||
}
|
||||
|
||||
$('#he-start-div').html(`<select required="required" id="module-he-start" name="module-he-start" class="form-control">` + options + `</select>`);
|
||||
options = "";
|
||||
selected = "";
|
||||
|
||||
for (let i = 1; i <= hemaxcount; i++) {
|
||||
options = options + '<option ' + selected + ' value="' + i + '">' + i + '</option>';
|
||||
}
|
||||
|
||||
$('#he-count-div').html(`<select required="required" id="module-he-count" name="module-he-count" class="form-control">` + options + `</select>`);
|
||||
|
||||
if (edit == 0) {
|
||||
$('#module-name-div').show();
|
||||
$('#module-name').removeAttr('disabled');
|
||||
@@ -225,9 +230,9 @@ $(document).ready(function () {
|
||||
$('#module-position-div').hide();
|
||||
$('#module-device-text').hide();
|
||||
$('#module-device-id').show();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$('#module-side').val(side);
|
||||
});
|
||||
|
||||
@@ -236,7 +241,6 @@ $(document).ready(function () {
|
||||
$('#module-name-div').hide();
|
||||
$('#module-name').attr('disabled', 'disabled');
|
||||
$('#module-device-div').show();
|
||||
|
||||
$('#module-device-id').removeAttr('disabled');
|
||||
$('#module-ports-div').hide();
|
||||
$('#module-plug-div').hide();
|
||||
@@ -266,6 +270,7 @@ $(document).ready(function () {
|
||||
var hemaxcountactive = 1
|
||||
var options;
|
||||
var selected;
|
||||
|
||||
for (let i = 1; i <= rackhe; i++) {
|
||||
if (hemaxcountactive == 1 && i > $(this).val() && !trigger.closest('tbody').find('tr').eq(i - 1).find('td').eq(1).hasClass('he-free')) {
|
||||
hemaxcountactive = 0;
|
||||
@@ -275,9 +280,11 @@ $(document).ready(function () {
|
||||
hemaxcount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 1; i <= hemaxcount; i++) {
|
||||
options = options + '<option ' + selected + ' value="' + i + '">' + i + '</option>';
|
||||
}
|
||||
|
||||
$('#he-count-div').html(`<select required="required" id="module-he-count" name="module-he-count" class="form-control">` + options + `</select>`);
|
||||
});
|
||||
|
||||
@@ -286,15 +293,14 @@ $(document).ready(function () {
|
||||
var rackid = trigger.closest('table').find('th').data('rackid');
|
||||
var endhe = parseInt($.trim($('#module-he-start').val())) + parseInt($.trim($('#module-he-count').val())) - 1;
|
||||
|
||||
|
||||
if (!$.trim($('#module-name').val()) && $.trim($('#module-type').val()) != "1" && $.trim($('#module-type').val()) != "0") {
|
||||
error = "Modul Name darf nicht leer sein";
|
||||
}
|
||||
|
||||
if ($.trim($('#module-type').val()) == "1" && !$.trim($('#module-device-id').val())) {
|
||||
error = "Kein Device ausgewählt";
|
||||
}
|
||||
|
||||
|
||||
if (!error) {
|
||||
$.post(linkAddModule + "&poprack_id=" + rackid, {
|
||||
side: $.trim($('#module-side').val()),
|
||||
@@ -308,14 +314,11 @@ $(document).ready(function () {
|
||||
width: $.trim($('#module-width').val()),
|
||||
status: $.trim($('#module-status').val()),
|
||||
position: $.trim($('#module-position').val())
|
||||
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
$('#rackModuleModal').modal('toggle');
|
||||
var currentSide = trigger.closest('tbody').data('side');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + currentSide, function (data, status) {
|
||||
trigger.closest('tbody').html(data);
|
||||
});
|
||||
updateAllRackViews(rackid, currentSide);
|
||||
}
|
||||
}, "json");
|
||||
} else {
|
||||
@@ -323,9 +326,11 @@ $(document).ready(function () {
|
||||
$(this).closest('.modal').find('.alert').show();
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", "#module-remove", function () {
|
||||
var moduleid = $(this).data('moduleid');
|
||||
var rackid = trigger.closest('table').find('th').data('rackid');
|
||||
|
||||
if (confirm("Modul entfernen?")) {
|
||||
let side = trigger.closest('tbody').data('side');
|
||||
$.post(linkRemoveModule, {
|
||||
@@ -333,21 +338,22 @@ $(document).ready(function () {
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
$('#rackModuleModal').modal('toggle');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + side, function (data, status) {
|
||||
trigger.closest('tbody').html(data);
|
||||
});
|
||||
updateAllRackViews(rackid, side);
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", "#module-update", function () {
|
||||
var moduleid = $(this).data('moduleid');
|
||||
var rackid = trigger.closest('table').find('th').data('rackid');
|
||||
var error;
|
||||
let side = trigger.closest('tbody').data('side');
|
||||
|
||||
if (!$.trim($('#module-name').val()) && $.trim($('#module-type').val()) != "1" && $.trim($('#module-type').val()) != "0") {
|
||||
error = "Modul Name darf nicht leer sein";
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
$.post(linkUpdateModule, {
|
||||
id: moduleid,
|
||||
@@ -359,9 +365,7 @@ $(document).ready(function () {
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
$('#rackModuleModal').modal('toggle');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + side, function (data, status) {
|
||||
trigger.closest('tbody').html(data);
|
||||
});
|
||||
updateAllRackViews(rackid, side);
|
||||
}
|
||||
}, "json");
|
||||
} else {
|
||||
@@ -378,6 +382,7 @@ $(document).ready(function () {
|
||||
if ($('#rack-he').val() < rackmin) {
|
||||
error = "Minimale Höheneinheiten: " + rackmin;
|
||||
}
|
||||
|
||||
if ($('#rack-he').val() > 60) {
|
||||
error = "Maximale Höheneinheiten: 60";
|
||||
}
|
||||
@@ -389,14 +394,15 @@ $(document).ready(function () {
|
||||
if (!$.trim($('#rack-he').val())) {
|
||||
error = "Höheneinheiten darf nicht leer sein";
|
||||
}
|
||||
|
||||
if (!$.trim($('#rack-name').val())) {
|
||||
error = "Schrank Name darf nicht leer sein";
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
$.post(linkEditRack + "&poprack_id=" + rackid, {
|
||||
name: $.trim($('#rack-name').val()),
|
||||
he: $.trim($('#rack-he').val())
|
||||
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
$('#rackModal').modal('toggle');
|
||||
@@ -408,6 +414,7 @@ $(document).ready(function () {
|
||||
$(this).closest('.modal').find('.alert').show();
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", "#rack-add", function () {
|
||||
var popid = $(this).data('popid');
|
||||
var error;
|
||||
@@ -415,6 +422,7 @@ $(document).ready(function () {
|
||||
if ($('#rack-he').val() < 1) {
|
||||
error = "Minimale Höheneinheiten: " + 1;
|
||||
}
|
||||
|
||||
if ($('#rack-he').val() > 60) {
|
||||
error = error = "Maximale Höheneinheiten: 60";
|
||||
}
|
||||
@@ -426,14 +434,15 @@ $(document).ready(function () {
|
||||
if (!$.trim($('#rack-he').val())) {
|
||||
error = "Höheneinheiten darf nicht leer sein";
|
||||
}
|
||||
|
||||
if (!$.trim($('#rack-name').val())) {
|
||||
error = "Schrank Name darf nicht leer sein";
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
$.post(linkAddRack + "&pop_id=" + popid, {
|
||||
name: $.trim($('#rack-name').val()),
|
||||
he: $.trim($('#rack-he').val())
|
||||
|
||||
}, function (data) {
|
||||
if (data.success === true) {
|
||||
$('#rackModal').modal('toggle');
|
||||
@@ -457,33 +466,29 @@ $(document).ready(function () {
|
||||
location.reload();
|
||||
}
|
||||
}, "json");
|
||||
|
||||
});
|
||||
|
||||
$("body").on("change", "#module-width", function () {
|
||||
if ($(this).val() == "12") {
|
||||
$('#module-position-div').hide();
|
||||
} else if ($(this).val() == "6") {
|
||||
$('#module-position').html(`<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
`);
|
||||
<option value="2">2</option>`);
|
||||
$('#module-position-div').show();
|
||||
} else if ($(this).val() == "4") {
|
||||
$('#module-position').html(`<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
`);
|
||||
<option value="3">3</option>`);
|
||||
$('#module-position-div').show();
|
||||
} else if ($(this).val() == "3") {
|
||||
$('#module-position').html(`<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
`);
|
||||
<option value="4">4</option>`);
|
||||
$('#module-position-div').show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("body").on("change", "#module-ports", function () {
|
||||
var plugs = [];
|
||||
if ($(this).find(':selected').data('plugs') !== undefined) {
|
||||
@@ -504,6 +509,7 @@ $(document).ready(function () {
|
||||
$("body").on("change", "#module-slot", function () {
|
||||
$('#module-position').val($(this).val());
|
||||
var parent = trigger.closest('tr');
|
||||
|
||||
if (trigger.closest('tr').find('td').eq(1).html() === undefined) {
|
||||
parent = trigger.closest('tr').prev();
|
||||
for (let i = 1; i <= rackhe; i++) {
|
||||
@@ -514,31 +520,35 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var newmodule = false;
|
||||
var tdnumber = parseInt($(this).val())
|
||||
|
||||
if (parent.find('td').eq(tdnumber).data('id') === undefined) {
|
||||
newmodule = true;
|
||||
}
|
||||
|
||||
if (!newmodule) {
|
||||
$('#module-remove').show();
|
||||
$('#module-update').show();
|
||||
$('#module-add').hide();
|
||||
|
||||
|
||||
$('#module-type').val(parent.find('td').eq(tdnumber).data('type')).change();
|
||||
|
||||
if ($('#module-type').val() == "1") {
|
||||
$('#module-device-id').hide();
|
||||
$('#module-device-text').text(parent.find('td').eq(tdnumber).data('name'));
|
||||
$('#module-device-text').show();
|
||||
}
|
||||
|
||||
if (parent.find('td').eq(tdnumber).data('ports') != "") {
|
||||
$('#module-ports').val(parent.find('td').eq(tdnumber).data('ports')).change();
|
||||
$('#module-plug').val(parent.find('td').eq(tdnumber).data('plug'));
|
||||
}
|
||||
|
||||
$('#module-type').attr('disabled', 'disabled');
|
||||
$('#module-name').val(parent.find('td').eq(tdnumber).data('name'));
|
||||
|
||||
|
||||
$('#module-remove').data('moduleid', parent.find('td').eq(tdnumber).data('id'));
|
||||
$('#module-update').data('moduleid', parent.find('td').eq(tdnumber).data('id'));
|
||||
} else {
|
||||
@@ -562,6 +572,7 @@ $(document).ready(function () {
|
||||
$('#module-device-text').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", ".switch-rack-side", function () {
|
||||
var icon = $(this);
|
||||
var rackTh = icon.closest('th');
|
||||
@@ -572,10 +583,13 @@ $(document).ready(function () {
|
||||
|
||||
var currentSide = rackBody.data('side');
|
||||
var newSide = (currentSide === 'front') ? 'back' : 'front';
|
||||
|
||||
if (icon.hasClass('is-loading')) {
|
||||
return;
|
||||
}
|
||||
|
||||
icon.addClass('is-loading fa-spin');
|
||||
|
||||
rackTable.fadeOut(150, function () {
|
||||
$.get(linkGenerateRack + "&id=" + rackId + "&side=" + newSide, function (data, status) {
|
||||
rackBody.html(data);
|
||||
@@ -586,6 +600,7 @@ $(document).ready(function () {
|
||||
} else {
|
||||
sideIndicator.text('- Rückseite');
|
||||
}
|
||||
|
||||
rackTable.fadeIn(150);
|
||||
}).fail(function () {
|
||||
rackBody.html('<tr><td colspan="13" class="text-center text-danger p-3">Fehler beim Laden.</td></tr>');
|
||||
@@ -595,335 +610,138 @@ $(document).ready(function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
let currentCableTrigger;
|
||||
|
||||
|
||||
$("body").on("click", ".cable-container", function (e) {
|
||||
$("body").on("click", ".rack-fullscreen-btn", function (e) {
|
||||
e.stopPropagation();
|
||||
let parentTd = $(this).closest('td');
|
||||
currentCableTrigger = parentTd;
|
||||
|
||||
let moduleId = parentTd.data('id');
|
||||
let totalPorts = parentTd.data('ports');
|
||||
let moduleName = parentTd.data('name');
|
||||
var $originalTable = $(this).closest('table');
|
||||
var rackName = $(this).closest('th').find('.rack-name').text().trim();
|
||||
var $clonedTable = $originalTable.clone();
|
||||
|
||||
$('#cableModal #cable-poprackmodule-id').val(moduleId);
|
||||
$('#cableModal #port-start, #cableModal #port-end').attr('max', totalPorts);
|
||||
$('#cableModal #cable-name, #cableModal #port-start, #cableModal #port-end').val('');
|
||||
$('#cableModal #cable-modal-alert').hide();
|
||||
$('#cableModal .modal-title').text('Kabel auf Panel ' + moduleName);
|
||||
$clonedTable.find('.move-handle, .switch-rack-side, .fa-edit, .fa-expand').remove();
|
||||
|
||||
$('#cableModal').modal('show');
|
||||
});
|
||||
|
||||
$("body").on("click", "#cable-add-button", function () {
|
||||
if (!currentCableTrigger) return;
|
||||
|
||||
let rackid = currentCableTrigger.closest('table').find('th').data('rackid');
|
||||
let modal = $('#cableModal');
|
||||
let alert = modal.find('#cable-modal-alert');
|
||||
let data = {
|
||||
poprackmodule_id: modal.find('#cable-poprackmodule-id').val(),
|
||||
cable_name: modal.find('#cable-name').val().trim(),
|
||||
port_start: parseInt(modal.find('#port-start').val()),
|
||||
port_end: parseInt(modal.find('#port-end').val()),
|
||||
fiber_start: parseInt(modal.find('#fiber-start').val()) || null,
|
||||
fiber_end: parseInt(modal.find('#fiber-end').val()) || null,
|
||||
description: modal.find('#cable-description').val().trim()
|
||||
};
|
||||
|
||||
if (!data.cable_name || !data.port_start || !data.port_end) {
|
||||
alert.text('Bitte alle Felder ausfüllen.').show();
|
||||
return;
|
||||
}
|
||||
if (data.port_start > data.port_end) {
|
||||
alert.text('Start-Port muss kleiner oder gleich dem End-Port sein.').show();
|
||||
return;
|
||||
}
|
||||
if (data.fiber_start && data.fiber_end) {
|
||||
if (data.fiber_start > data.fiber_end) {
|
||||
alert.text('Faser-Start muss kleiner oder gleich Faser-Ende sein.').show();
|
||||
return;
|
||||
}
|
||||
const portCount = data.port_end - data.port_start + 1;
|
||||
const fiberCount = data.fiber_end - data.fiber_start + 1;
|
||||
if (fiberCount > portCount) {
|
||||
alert.text('Die Anzahl der Fasern (' + fiberCount + ') darf nicht größer als die Anzahl der Ports (' + portCount + ') sein.').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
$.post(linkAddCable, data, function (response) {
|
||||
if (response.success) {
|
||||
modal.modal('hide');
|
||||
let currentSide = currentCableTrigger.closest('tbody').data('side');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + currentSide, function (html) {
|
||||
currentCableTrigger.closest('tbody').html(html);
|
||||
});
|
||||
} else {
|
||||
alert.text(response.error || 'Fehler beim Speichern.').show();
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
let currentCableElement;
|
||||
let cableMenuPopper = null;
|
||||
|
||||
function showCableMenuAtEvent(e) {
|
||||
const $menu = $('#cable-context-menu');
|
||||
if (!$menu.length) return;
|
||||
$menu.removeAttr('x-placement');
|
||||
if ($menu.parent()[0] !== document.body) $menu.detach().appendTo('body');
|
||||
$menu.css({display: 'block'}).addClass('show');
|
||||
const el = $menu[0];
|
||||
const w = $menu.outerWidth(), h = $menu.outerHeight();
|
||||
const vw = window.innerWidth, vh = window.innerHeight;
|
||||
|
||||
let x = e.clientX, y = e.clientY;
|
||||
if (x + w > vw) x = vw - w - 6;
|
||||
if (y + h > vh) y = vh - h - 6;
|
||||
|
||||
el.style.setProperty('position', 'fixed', 'important');
|
||||
el.style.setProperty('left', x + 'px', 'important');
|
||||
el.style.setProperty('top', y + 'px', 'important');
|
||||
el.style.setProperty('z-index', '2147483000', 'important');
|
||||
}
|
||||
|
||||
$('body').on('contextmenu click', '.cable-item', function (e) {
|
||||
if (e.type === 'contextmenu' || e.type === 'click') {
|
||||
if (e.which !== 1) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
currentCableElement = $(this);
|
||||
$('.dropdown-menu').not('#cable-context-menu').removeClass('show').hide();
|
||||
showCableMenuAtEvent(e);
|
||||
requestAnimationFrame(() => {
|
||||
const el = document.getElementById('cable-context-menu');
|
||||
console.log('OPEN fired, ctx styles =', el ? el.style.cssText : 'NO ELEMENT');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function hideCableMenu() {
|
||||
const $m = $('#cable-context-menu');
|
||||
const el = $m[0];
|
||||
if (!$m.length) return;
|
||||
|
||||
$m.removeClass('show').hide();
|
||||
|
||||
if (el) {
|
||||
el.style.removeProperty('top');
|
||||
el.style.removeProperty('left');
|
||||
el.style.removeProperty('position');
|
||||
el.style.removeProperty('z-index');
|
||||
}
|
||||
}
|
||||
|
||||
$('#cable-context-menu')
|
||||
.off('mousedown.ctx click.ctx contextmenu.ctx')
|
||||
.on('mousedown.ctx click.ctx contextmenu.ctx', function (e) {
|
||||
e.stopPropagation();
|
||||
$clonedTable.css({
|
||||
'width': '800px',
|
||||
'margin': '0 auto',
|
||||
'background-color': '#fff',
|
||||
'box-shadow': 'none'
|
||||
});
|
||||
|
||||
$(document)
|
||||
.off('mousedown.ctx click.ctx contextmenu.ctx keydown.ctx')
|
||||
.on('mousedown.ctx click.ctx contextmenu.ctx', function (e) {
|
||||
if ($(e.target).closest('#cable-context-menu').length) return;
|
||||
hideCableMenu();
|
||||
})
|
||||
.on('keydown.ctx', function (e) {
|
||||
if (e.key === 'Escape' || e.keyCode === 27) hideCableMenu();
|
||||
});
|
||||
|
||||
$(window)
|
||||
.off('scroll.ctx resize.ctx')
|
||||
.on('scroll.ctx resize.ctx', hideCableMenu);
|
||||
|
||||
$('#cable-context-menu .dropdown-item').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
hideCableMenu();
|
||||
|
||||
const action = $(this).data('action');
|
||||
const rackid = currentCableElement.closest('table').find('th').data('rackid');
|
||||
const cableId = currentCableElement.data('cable-id');
|
||||
const cableName = currentCableElement.data('cable-name');
|
||||
|
||||
switch (action) {
|
||||
case 'view':
|
||||
alert("Detailansicht für Kabel '" + cableName + "' (ID: " + cableId + ")");
|
||||
break;
|
||||
|
||||
case 'edit': {
|
||||
const cableId = currentCableElement.data('cable-id');
|
||||
const cableName = currentCableElement.data('cable-name');
|
||||
const portStart = currentCableElement.data('port-start');
|
||||
const portEnd = currentCableElement.data('port-end');
|
||||
const fiberStart = currentCableElement.data('fiber-start');
|
||||
const fiberEnd = currentCableElement.data('fiber-end');
|
||||
const description = currentCableElement.data('description');
|
||||
$('#edit-cable-id').val(cableId);
|
||||
$('#edit-cable-name').val(cableName);
|
||||
$('#edit-port-start').val(portStart);
|
||||
$('#edit-port-end').val(portEnd);
|
||||
$('#edit-fiber-start').val(fiberStart);
|
||||
$('#edit-fiber-end').val(fiberEnd);
|
||||
$('#edit-cable-description').val(description);
|
||||
$('#cable-edit-modal-alert').hide();
|
||||
$('#cableEditModal').modal('show');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'delete':
|
||||
if (confirm("Kabel '" + cableName + "' wirklich entfernen?")) {
|
||||
$.post(linkRemoveCable, {id: cableId}, function (response) {
|
||||
if (response.success) {
|
||||
let currentSide = currentCableElement.closest('tbody').data('side');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + currentSide, function (html) {
|
||||
currentCableElement.closest('tbody').html(html);
|
||||
});
|
||||
} else {
|
||||
alert('Fehler beim Löschen des Kabels.');
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
break;
|
||||
}
|
||||
$('#overlayTitle').text(rackName);
|
||||
$('#overlayContent').html($clonedTable);
|
||||
$('#customRackOverlay').fadeIn();
|
||||
$('body').css('overflow', 'hidden');
|
||||
$('#overlayContent [data-toggle="popover"]').popover();
|
||||
});
|
||||
|
||||
$("body").on("click", "#cable-update-button", function () {
|
||||
const modal = $('#cableEditModal');
|
||||
const cableId = modal.find('#edit-cable-id').val();
|
||||
const rackid = currentCableElement.closest('table').find('th').data('rackid');
|
||||
|
||||
const data = {
|
||||
id: cableId,
|
||||
cable_name: modal.find('#edit-cable-name').val().trim(),
|
||||
port_start: parseInt(modal.find('#edit-port-start').val()),
|
||||
port_end: parseInt(modal.find('#edit-port-end').val()),
|
||||
fiber_start: parseInt(modal.find('#edit-fiber-start').val()) || null,
|
||||
fiber_end: parseInt(modal.find('#edit-fiber-end').val()) || null,
|
||||
description: modal.find('#edit-cable-description').val().trim()
|
||||
};
|
||||
if (data.fiber_start && data.fiber_end) {
|
||||
if (data.fiber_start > data.fiber_end) {
|
||||
modal.find('#cable-edit-modal-alert').text('Faser-Start muss kleiner oder gleich Faser-Ende sein.').show();
|
||||
return;
|
||||
}
|
||||
const portCount = data.port_end - data.port_start + 1;
|
||||
const fiberCount = data.fiber_end - data.fiber_start + 1;
|
||||
if (fiberCount > portCount) {
|
||||
modal.find('#cable-edit-modal-alert').text('Die Anzahl der Fasern (' + fiberCount + ') darf nicht größer als die Anzahl der Ports (' + portCount + ') sein.').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$.post(linkUpdateCable, data, function (response) {
|
||||
if (response.success) {
|
||||
modal.modal('hide');
|
||||
let currentSide = currentCableElement.closest('tbody').data('side');
|
||||
$.get(linkGenerateRack + "&id=" + rackid + "&side=" + currentSide, function (html) {
|
||||
currentCableElement.closest('tbody').html(html);
|
||||
});
|
||||
} else {
|
||||
modal.find('#cable-edit-modal-alert').text(response.error || 'Fehler beim Speichern.').show();
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
function updateAllRackViews(rackId, side) {
|
||||
$.get(linkGenerateRack + "&id=" + rackId + "&side=" + side, function (data) {
|
||||
var $targets = $('tbody[id="rack-body-' + rackId + '"]');
|
||||
$targets.html(data);
|
||||
$targets.data('side', side);
|
||||
$targets.find('[data-toggle="popover"]').popover();
|
||||
});
|
||||
|
||||
function initCableSearch() {
|
||||
// Zerstöre eine eventuell bereits existierende Select2-Instanz
|
||||
if ($('#cable-search').data('select2')) {
|
||||
$('#cable-search').select2('destroy');
|
||||
}
|
||||
$('#cable-search').empty().append(new Option());
|
||||
|
||||
// 1. Kabel nach Namen gruppieren und Fasern summieren
|
||||
let cableGroups = {};
|
||||
$('.cable-item').each(function () {
|
||||
const $cableElement = $(this);
|
||||
const cableName = $cableElement.data('cable-name');
|
||||
|
||||
// Überspringe Elemente ohne Kabelnamen
|
||||
if (!cableName) return;
|
||||
|
||||
// Berechne die Anzahl der Fasern für DIESES Segment
|
||||
let fiberCount = 0;
|
||||
const fiberStart = parseInt($cableElement.data('fiber-start'));
|
||||
const fiberEnd = parseInt($cableElement.data('fiber-end'));
|
||||
if (!isNaN(fiberStart) && !isNaN(fiberEnd)) {
|
||||
fiberCount = (fiberEnd - fiberStart) + 1;
|
||||
}
|
||||
function printRackOverlay(orientation = 'landscape') {
|
||||
printJS({
|
||||
printable: 'overlayContent',
|
||||
type: 'html',
|
||||
targetStyles: ['*'],
|
||||
style: `
|
||||
@page {
|
||||
size: ${orientation};
|
||||
margin: 5mm;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
}
|
||||
|
||||
// Wenn die Gruppe für diesen Namen noch nicht existiert, erstelle sie
|
||||
if (!cableGroups[cableName]) {
|
||||
cableGroups[cableName] = {
|
||||
totalFibers: 0
|
||||
};
|
||||
* {
|
||||
color: #000 !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
// Addiere die Fasern zur Gesamtsumme der Gruppe
|
||||
cableGroups[cableName].totalFibers += fiberCount;
|
||||
});
|
||||
|
||||
// 2. Erstelle die Datenquelle für Select2 aus den gruppierten Daten
|
||||
let cableSearchData = [];
|
||||
for (const name in cableGroups) {
|
||||
let label = `Kabel: ${name}`;
|
||||
if (cableGroups[name].totalFibers > 0) {
|
||||
label += ` (Gesamt: ${cableGroups[name].totalFibers} Fasern)`;
|
||||
table {
|
||||
width: 100% !important;
|
||||
border-collapse: collapse !important;
|
||||
table-layout: fixed !important;
|
||||
font-size: ${orientation === 'landscape' ? '10px' : '8px'} !important;
|
||||
}
|
||||
td, th {
|
||||
padding: 1px !important;
|
||||
border: 1px solid #666 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Die "id" ist jetzt der eindeutige Kabelname
|
||||
cableSearchData.push({
|
||||
id: name,
|
||||
text: label
|
||||
});
|
||||
}
|
||||
.rack-color-lwl { background-color: #81df44 !important; }
|
||||
.rack-color-lwl-planned { background-color: #ff0000 !important; }
|
||||
.rack-color-device { background-color: #b6c6f0 !important; }
|
||||
.rack-color-infra { background-color: #f7b876 !important; }
|
||||
.rack-color-panel { background-color: #96f3de !important; }
|
||||
.rack-color-blocked { background-color: #ff0000 !important; }
|
||||
.rack-color-rpanel { background-color: #58c9f0 !important; }
|
||||
|
||||
.cable-container {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-height: 40px;
|
||||
align-items: stretch !important;
|
||||
background-color: #fffbe9 !important;
|
||||
}
|
||||
|
||||
// 3. Select2 mit den gruppierten Daten initialisieren
|
||||
$('#cable-search').select2({
|
||||
data: cableSearchData,
|
||||
placeholder: "Kabelname suchen...",
|
||||
allowClear: true,
|
||||
});
|
||||
}
|
||||
.cable-item {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
justify-content: flex-start !important;
|
||||
align-items: flex-start !important;
|
||||
box-sizing: border-box !important;
|
||||
overflow: hidden !important;
|
||||
padding: 2px !important;
|
||||
text-align: left !important;
|
||||
border-right: 1px solid #797979 !important;
|
||||
background-color: #e1ffdf !important;
|
||||
}
|
||||
|
||||
$('#cable-search').on('select2:select', function (e) {
|
||||
const selectedData = e.params.data;
|
||||
.hide-if-narrow { display: block !important; }
|
||||
|
||||
.cable-item b {
|
||||
font-size: ${orientation === 'landscape' ? '9px' : '7px'} !important;
|
||||
white-space: normal !important;
|
||||
line-height: 1.1 !important;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
// Die "id" aus der Auswahl ist jetzt der Kabelname
|
||||
const selectedCableName = selectedData.id;
|
||||
if (!selectedCableName) return;
|
||||
.cable-description {
|
||||
white-space: normal !important;
|
||||
font-size: ${orientation === 'landscape' ? '8px' : '7px'} !important;
|
||||
line-height: 1.0 !important;
|
||||
font-style: italic !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.port-ranges-container {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
font-size: ${orientation === 'landscape' ? '8px' : '7px'} !important;
|
||||
margin-top: 2px !important;
|
||||
line-height: 1.0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// 1. Finde ALLE .cable-item Elemente, die diesen Kabelnamen haben
|
||||
const $targetElements = $('.cable-item[data-cable-name="' + selectedCableName + '"]');
|
||||
|
||||
if ($targetElements.length === 0) {
|
||||
console.error("Keine Kabel-Elemente mit dem Namen '" + selectedCableName + "' gefunden.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Alle alten Markierungen entfernen
|
||||
$('.cable-highlight, .cable-flash').removeClass('cable-highlight cable-flash');
|
||||
$('.module-highlight').removeClass('module-highlight');
|
||||
|
||||
// 2. Scrolle zum ERSTEN gefundenen Element
|
||||
|
||||
|
||||
// 3. Hebe ALLE gefundenen Elemente und ihre zugehörigen Module hervor
|
||||
$targetElements.each(function () {
|
||||
const $el = $(this);
|
||||
const $parentModule = $el.closest('td');
|
||||
|
||||
$el.addClass('cable-highlight cable-flash');
|
||||
$parentModule.addClass('module-highlight');
|
||||
});
|
||||
#overlayContent { width: 100%; display: block; }
|
||||
|
||||
.rack-fullscreen-btn, .switch-rack-side, .move-handle, .fa-edit {
|
||||
display: none !important;
|
||||
}
|
||||
`
|
||||
});
|
||||
$('#cable-search').on('change', function (e) {
|
||||
if ($(this).val() === null || $(this).val() === '') {
|
||||
$('.cable-highlight, .cable-flash').removeClass('cable-highlight cable-flash');
|
||||
$('.module-highlight').removeClass('module-highlight');
|
||||
}
|
||||
});
|
||||
|
||||
initCableSearch();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user