Devices Feature Erweiterung

* manueller Config Upload wurde integriert
*
This commit is contained in:
Daniel Spitzer
2025-04-15 10:42:39 +02:00
parent cd7abf0607
commit 48edde27ef
3 changed files with 197 additions and 0 deletions

View File

@@ -135,6 +135,17 @@
padding: 6px 0.85rem 6px 0.85rem !important; padding: 6px 0.85rem 6px 0.85rem !important;
} }
.fa-fileupload {
font-size: 28px;
color: #128a01;
margin-top: 4px;
cursor: pointer;
}
.form-label-upload {
margin-top: 10px;
}
</style> </style>
<!-- start page title --> <!-- start page title -->
@@ -337,15 +348,20 @@ foreach ($devicesall as $deviceall) {
<?php <?php
} }
?> ?>
</div> </div>
<?php if ($me->is('Admin')) : ?> <?php if ($me->is('Admin')) : ?>
<div class="col-12 col-lg-3 card-border"> <div class="col-12 col-lg-3 card-border">
<div class="overflow-auto"> <div class="overflow-auto">
<h4 class="float-left">Config Backups</h4> <h4 class="float-left">Config Backups</h4>
<?php if ($devices->devicetype->devicemanufactor->config_backup > count()): ?> <?php if ($devices->devicetype->devicemanufactor->config_backup > count()): ?>
<span><i title="Switch config" class="fa-light fa-rectangle-code code-ico" <span><i title="Switch config" class="fa-light fa-rectangle-code code-ico"
data-toggle="modal" data-target="#configCode"></i></span> data-toggle="modal" data-target="#configCode"></i></span>
<?php endif; <?php endif;
?>
<?php
if ($me->is('Admin')): if ($me->is('Admin')):
?> ?>
<div class="float-right"> <div class="float-right">
@@ -354,8 +370,30 @@ foreach ($devicesall as $deviceall) {
<button class="btn btn-primary "><span id="create-backup-button-text">Backup erstellen</span> <button class="btn btn-primary "><span id="create-backup-button-text">Backup erstellen</span>
<span id="create-backup-load"></i></span></button> <span id="create-backup-load"></i></span></button>
</a></div> </a></div>
<span class="float-right mr-2"><i
class="fa-solid fa-cloud-arrow-up fa-fileupload"></i></span>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div id="documents-upload" class="row mt-2 mb-2 justify-content-start" style="display: none">
<div class="col-5 col-lg-4 text-center"><label
class="form-label form-label-upload">Backup Upload</label></div>
<div class="col-19 col-lg-8" id="attachments" data-newkey="">
<div class="input-group mb-2">
<div class="custom-file">
<input type="file" class="custom-file-input" id="files-input"
name="files[]"
multiple>
<label class="custom-file-label" for="files-input"
aria-describedby="">Datei(en)</label>
</div>
</div>
<div class="attachment-div mb-2"></div>
<div id="uploadsts"></div>
</div>
</div>
<?php <?php
if ($devicesconfig->success == "true" && $devicesconfig->data > count()) { if ($devicesconfig->success == "true" && $devicesconfig->data > count()) {
?> ?>
@@ -683,6 +721,64 @@ foreach ($devicesall as $deviceall) {
<script type="text/javascript"> <script type="text/javascript">
const customers =<?php echo json_encode($customer); ?>; const customers =<?php echo json_encode($customer); ?>;
function uploadajax(totalFiles, currentIndex) {
let fileList = $('#files-input').prop("files");
let form_data = new FormData();
form_data.append("files[]", fileList[currentIndex]);
if ($('.fa-folder-open').data('id')) {
form_data.append("folder_id", $('.fa-folder-open').data('id'));
}
$.ajax({
url: '<?= self::getUrl("Device", "api", ['do' => 'uploadFile', 'id' => $devices->id]) ?>',
cache: false,
contentType: false,
processData: false,
async: true,
data: form_data,
type: 'POST',
xhr: function () {
let xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (event) {
let percent = 0;
if (event.lengthComputable) {
percent = Math.ceil(event.loaded / event.total * 100);
}
$('.pb-' + currentIndex).css('width', percent + '%')
.attr('aria-valuenow', percent);
}, false);
}
return xhr;
},
success: function (res, status) {
$('.pb-' + currentIndex).closest('.progress').remove();
if (currentIndex < totalFiles - 1) {
uploadajax(totalFiles, currentIndex + 1);
} else {
window.location.reload();
}
},
error: function (res) {
alert('Upload fehlgeschlagen.');
}
});
}
function formatFileSize(bytes) {
if (bytes >= 1024 * 1024) {
const megabytes = bytes / (1024 * 1024);
return megabytes.toFixed(2) + ' MB';
} else if (bytes >= 1024) {
const kilobytes = bytes / 1024;
return kilobytes.toFixed(2) + ' KB';
} else {
return Math.round(bytes) + ' Bytes'; // Keine Nachkommastellen
}
}
$(document).ready(function () { $(document).ready(function () {
@@ -1304,6 +1400,34 @@ foreach ($devicesall as $deviceall) {
; ;
}); });
$('[data-toggle="tooltip"]').tooltip() $('[data-toggle="tooltip"]').tooltip()
$(document).on('change', '#files-input', function () {
let fileList = $('#files-input').prop("files");
// Leeren des Upload-Status-Containers
$('#uploadsts').html('');
$('.attachment-div').html('');
// Erzeuge für jede Datei einen eigenen Fortschrittsbalken (eindeutig per Index)
for (let i = 0; i < fileList.length; i++) {
$('.attachment-div').append(`
<div class="progress" style="margin-bottom: 10px;">
<div class="progress-bar progress-bar-striped progress-bar-animated pb-${i}"
role="progressbar"
style="width: 0%;"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"></div>
</div>
`);
}
if (fileList.length > 0) {
uploadajax(fileList.length, 0);
}
});
$(document).on('click', '.fa-fileupload', function () {
$('#documents-upload').toggle();
});
}); });
</script> </script>

View File

@@ -318,6 +318,9 @@ class DeviceController extends mfBaseController
case "createconfig": case "createconfig":
$this->createConfig($ip); $this->createConfig($ip);
break; break;
case "uploadFile":
$this->uploadFile($id);
break;
case "getoltinfo": case "getoltinfo":
$this->getoltInfo($ip, $portid, $adv); $this->getoltInfo($ip, $portid, $adv);
break; break;
@@ -361,6 +364,15 @@ class DeviceController extends mfBaseController
exit; exit;
} }
private function uploadFile($id)
{
$r = $this->request;
$file = $_FILES;
$response = DeviceModel::uploadFile($id, $file);
echo $response;
die();
}
private function createConfig($ip) private function createConfig($ip)
{ {

View File

@@ -362,4 +362,65 @@ class DeviceModel
endif; endif;
return json_decode($response); return json_decode($response);
} }
public static function uploadFile($id, $file)
{
$response = "";
if (TT_MBI_API_ENABLE) {
// Überprüfe, ob im $_FILES-Array ein 'files'-Eintrag vorhanden ist
// und ob mindestens eine Datei hochgeladen wurde.
if (!isset($_FILES['files']) || !isset($_FILES['files']['tmp_name'][0]) || empty($_FILES['files']['tmp_name'][0])) {
return json_encode(["error" => "Dateiupload fehlgeschlagen: Keine Datei unter 'files' gefunden."]);
}
// Baue die URL zusammen
$url = TT_MBI_API_URL . TT_MBI_API_VERSION . '/deviceuploadfile/' . $id;
// Erstelle ein CURLFile-Objekt aus dem ersten (und evtl. einzigen) Element
$curlFile = new CURLFile(
$_FILES['files']['tmp_name'][0],
$_FILES['files']['type'][0],
$_FILES['files']['name'][0]
);
// Bereite die POST-Daten vor: Der Schlüssel "file" entspricht
// eventuell den Erwartungen der API.
$postFields = ['file' => $curlFile];
// cURL-Handle initialisieren und Optionen setzen
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . TT_MBI_API_KEY
]
]);
// Führe die Anfrage aus
$response = curl_exec($curl);
// Fehlerbehandlung: Bei einem cURL-Fehler gebe diesen als JSON zurück
if (curl_errno($curl)) {
$error_msg = curl_error($curl);
curl_close($curl);
return json_encode(["error" => $error_msg]);
}
// Schließe den cURL-Handle
curl_close($curl);
}
// Dekodiere die Antwort und gebe sie zurück
return json_decode($response);
}
} }