Semi-stable version with old variable names
This commit is contained in:
@@ -12,6 +12,16 @@ ini_wkvs_session(true);
|
||||
$csrf_token = $_SESSION['csrf_token'] ?? '';
|
||||
|
||||
$access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
@@ -30,23 +40,13 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
<link rel="stylesheet" href="/files/fonts/fonts.css">
|
||||
<link rel="stylesheet" href="/intern/css/sidebar.css">
|
||||
|
||||
<link rel="stylesheet" href="/intern/css/user.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<body class="displaycontrol">
|
||||
|
||||
<?php
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
@@ -72,7 +72,12 @@ $disciplines = $result->fetch_all(MYSQLI_ASSOC);
|
||||
$stmt->close();
|
||||
|
||||
$currentPage = 'displaycontrol';
|
||||
require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
require $baseDir . '/../scripts/sidebar/sidebar.php';
|
||||
|
||||
$WSaccesstype = "wk_leitung";
|
||||
$WSaccess = "displaycontrol";
|
||||
$WSaccessPermission = "W";
|
||||
|
||||
?>
|
||||
|
||||
<script>
|
||||
@@ -81,18 +86,33 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
const RETRY_DELAY = 2000;
|
||||
const csrf_token = "<?= $csrf_token ?>";
|
||||
|
||||
const WSaccesstype = "<?= $WSaccesstype ?>";
|
||||
const WSaccess = "<?= $WSaccess ?>";
|
||||
const WSaccessPermission = "<?= $WSaccessPermission ?>"
|
||||
|
||||
const urlAjaxNewWSToken = '/intern/scripts/ajax-create-ws-token.php';
|
||||
|
||||
async function fetchNewWSToken(freigabe) {
|
||||
async function fetchNewWSToken(accesstype, access, accessPermission) {
|
||||
try {
|
||||
const response = await fetch(urlAjaxNewWSToken, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({ access: freigabe, csrf_token })
|
||||
body: new URLSearchParams({
|
||||
csrf_token,
|
||||
accesstype,
|
||||
access,
|
||||
accessPermission
|
||||
})
|
||||
});
|
||||
|
||||
if (response.status === 403) {
|
||||
console.warn("Please Re-Autenithicate. Reloading page...");
|
||||
location.reload();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = await response.json();
|
||||
@@ -108,9 +128,9 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
|
||||
let token;
|
||||
if (firstConnect) {
|
||||
token = '<?= generateWSToken('displaycontrol') ?>';
|
||||
token = '<?= generateWSAdminToken($WSaccesstype, $WSaccess) ?>';
|
||||
} else {
|
||||
token = await fetchNewWSToken('displaycontrol');
|
||||
token = await fetchNewWSToken(WSaccesstype, WSaccess, WSaccessPermission);
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
@@ -159,7 +179,9 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
<div class="headingPanelDiv">
|
||||
<h2 class="headingPanel">Anzeigesteuerung</h2>
|
||||
</div>
|
||||
<?php sidebarRender('button'); ?>
|
||||
<div class="menuWrapper">
|
||||
<?php sidebarRender('button'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php sidebarRender('modal'); ?>
|
||||
@@ -174,7 +196,7 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
</div>
|
||||
<form class="change-type-form" data-type="ctext">
|
||||
<button type="submit">Individueller Text</button>
|
||||
<input placeholder="Individuellen Text eingeben...">
|
||||
<textarea placeholder="Individuellen Text eingeben..."></textarea>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -185,7 +207,7 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
echo '<iframe
|
||||
id="inlineFrame-'.$dis['name'].'"
|
||||
title="Display '.$dis['name'].'"
|
||||
src="/displays/display.php/?geraet='.$dis['name'].'">
|
||||
src="/externe-geraete/display/'. strtolower($dis['name']).'">
|
||||
</iframe></div>';
|
||||
}
|
||||
?>
|
||||
@@ -209,8 +231,8 @@ require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
event.preventDefault();
|
||||
const $form = $(this);
|
||||
const typeValue = $form.data('type');
|
||||
const ctext = $form.find('input').val() || '';
|
||||
sendType(typeValue, $form.find('input'), ctext);
|
||||
const ctext = $form.find('textarea').val() || '';
|
||||
sendType(typeValue, $form.find('textarea'), ctext);
|
||||
});
|
||||
|
||||
function sendType(typeValue, $element, ctext) {
|
||||
|
||||
+2091
-626
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session(true);
|
||||
|
||||
$csrf_token = $_SESSION['csrf_token'] ?? '';
|
||||
|
||||
$access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
|
||||
header("Location: /intern/wk-leitung/rechnungen");
|
||||
exit;
|
||||
|
||||
endif;
|
||||
+993
-1122
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,15 @@ $csrf_token = $_SESSION['csrf_token'] ?? '';
|
||||
|
||||
$access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
@@ -33,6 +42,9 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<link rel="stylesheet" href="/intern/css/sidebar.css">
|
||||
<link rel="stylesheet" href="/files/fonts/fonts.css">
|
||||
<script src="/intern/js/jquery/jquery-3.7.1.min.js"></script>
|
||||
<script src="/intern/js/chart/chart.js"></script>
|
||||
<link rel="stylesheet" href="/intern/css/user.css">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
let lastWrite = 0;
|
||||
@@ -47,21 +59,11 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
}, { passive: true });
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<body class="rechnungen">
|
||||
<?php
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
@@ -78,7 +80,7 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
$currentPage = 'rechnungen';
|
||||
|
||||
require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
require $baseDir . '/../scripts/sidebar/sidebar.php';
|
||||
|
||||
setlocale(LC_TIME, 'de_DE.UTF-8');
|
||||
|
||||
@@ -127,6 +129,8 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
return "Zahlungseingang überprüfen";
|
||||
case 2:
|
||||
return "Bezahlte Rechnungen";
|
||||
case 3:
|
||||
return "Stornierte Rechnungen";
|
||||
default:
|
||||
return "FEHLER BEI NAMENSGENERRIERUNG";
|
||||
}
|
||||
@@ -138,6 +142,8 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
return "inProcess";
|
||||
case 2:
|
||||
return "payed";
|
||||
case 3:
|
||||
return "storniert";
|
||||
default:
|
||||
return "notPayed";
|
||||
}
|
||||
@@ -168,7 +174,6 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
</label>
|
||||
<!-- Hidden field for backend -->
|
||||
<input type="hidden" id="scorNumberRaw" name="scor_reference">
|
||||
|
||||
<button id="submitScorNumber">Bestätigen</button>
|
||||
|
||||
</div>
|
||||
@@ -184,8 +189,12 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
</div>
|
||||
<div class="menuWrapper">
|
||||
<div class="trainerBurgerMenuDiv">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
||||
<svg viewBox="0 0 24 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v24a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1z" stroke="currentColor" stroke-width="1.5"/><path d="M7 5h10M7 8h10M7 11h5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
<path stroke="currentColor" stroke-dasharray="2 1" d="M4 16h16"/>
|
||||
<rect x="6" y="18" width="5" height="5" rx=".5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path fill="currentColor" d="M8 20h1v1H8z"/>
|
||||
<path d="M13 19h4m-4 2h4m-4 2h2" stroke="currentColor" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<?php sidebarRender('button'); ?>
|
||||
@@ -271,6 +280,10 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<h3>Keine erstellten Rechungen vorhanden</h3>
|
||||
<?php else :?>
|
||||
|
||||
<div style="width: 200px;">
|
||||
<canvas id="rechnungenOverviewChart"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
@@ -288,11 +301,14 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
|
||||
<ul class="selectOptions">
|
||||
<li data-value="deleteEntrys">Rechnungen stornieren</li>
|
||||
<li data-value="payEntrys">Rechnungen bezahlt</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<input type="submit" name="apply_bulk_action" class="bulkSelectSubmit" value="Anwenden">
|
||||
</div>
|
||||
|
||||
<?php $totalOrderVolumeArray = []; ?>
|
||||
|
||||
|
||||
<?php foreach ($allRechnungen as $status => $oneRechnungsStatus) : ?>
|
||||
@@ -303,7 +319,7 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<tr>
|
||||
<th style="width:20px;">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="check_all_<?= titleStatus(intval($status)) ?>">
|
||||
<input type="checkbox" class="masterCheckbox" data-type="<?= $status ?>">
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</th>
|
||||
@@ -312,6 +328,7 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<th>Typ</th>
|
||||
<th>Ersteller</th>
|
||||
<th>Datum</th>
|
||||
<th>Änderung</th>
|
||||
<th>Betrag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -320,13 +337,13 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<tr>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="bulk_ids[]" class="row_check_<?= titleStatus(intval($status)) ?>" value="<?= intval($row['order_id']) ?>">
|
||||
<input type="checkbox" name="bulk_ids[]" class="rowCheckbox" data-type="<?= $status ?>" value="<?= intval($row['order_id']) ?>">
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (file_exists($baseDir . "/../private-files/rechnungen/" . intval($row['order_id']) . ".pdf")) : ?>
|
||||
<a href="/intern/wk-leitung/rechnungen_viewer?order_id=<?= intval($row['order_id']) ?>" target="_blank">
|
||||
<a href="/intern/wk-leitung/rechnungen-viewer?order_id=<?= intval($row['order_id']) ?>" target="_blank">
|
||||
<?= intval($row['order_id']) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
@@ -352,17 +369,22 @@ $access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
|
||||
<td><?= htmlspecialchars($row['order_creator']) ?></td>
|
||||
|
||||
<td><?= htmlspecialchars(strftime('%d. %B %Y', (new DateTime($row['timestamp']))->getTimestamp())) ?></td>
|
||||
<td><?= htmlspecialchars(number_format(floatval($row['preis']), 2)) ?> CHF</td>
|
||||
<td><?= htmlspecialchars(strftime('%d. %B %Y', (new DateTime($row['edited_at']))->getTimestamp())) ?></td>
|
||||
<td>CHF <?= htmlspecialchars(number_format(floatval($row['preis']), 2)) ?></td>
|
||||
<?php $totalOrderVolume += floatval($row['preis']); ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="totalTr">
|
||||
<td colspan="6" class="totalTd"></td>
|
||||
<td class="totalValue"><span class="<?= classStatus(intval($status)) ?>"><?= htmlspecialchars(number_format(floatval($totalOrderVolume), 2))?> CHF</span></td>
|
||||
<td colspan="7" class="totalTd"></td>
|
||||
<td class="totalValue"><span class="<?= classStatus(intval($status)) ?>">CHF <?= htmlspecialchars(number_format(floatval($totalOrderVolume), 2))?></span></td>
|
||||
</tr>
|
||||
<?php $totalOrderVolumeArray[$status] = number_format(floatval($totalOrderVolume), 2); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach; ?>
|
||||
<div>
|
||||
<button class="buttonDownload" id="downloadRechnungenProtokoll">Protokoll Rechnungsänderungen herunterladen</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -409,12 +431,53 @@ $input.on('input', function() {
|
||||
$(this).val(formatted);
|
||||
});
|
||||
|
||||
$('#downloadRechnungenProtokoll').on('click', function() {
|
||||
const $button = $(this);
|
||||
|
||||
$button.addClass('opacity50');
|
||||
|
||||
const url = '/intern/scripts/rechnungen/ajax-neu_protokoll.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
csrf_token
|
||||
})
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error('Network response was not ok');
|
||||
|
||||
return res.blob().then(blob => ({ type: 'blob', data: blob }));
|
||||
})
|
||||
.then(result => {
|
||||
if (result.type === 'blob') {
|
||||
const url = window.URL.createObjectURL(result.data);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = "Protokoll_Rechnungen.pdf";
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
displayMsg(1, "Protokoll wurde erfolgreich heuntergeladen.");
|
||||
}
|
||||
$button.removeClass('opacity50');
|
||||
})
|
||||
.catch(err => {
|
||||
displayMsg(0, "Error processing request:", err);
|
||||
console.error("Error processing request:", err);
|
||||
$button.removeClass('opacity50');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('#submitScorNumber').on('click', function(e) {
|
||||
e.preventDefault(); // prevent form submission if it's a button
|
||||
|
||||
const SCOR = $('#scorNumberRaw').val();
|
||||
|
||||
fetch('/intern/scripts/rechnungen/ajax_update_order_status.php', {
|
||||
fetch('/intern/scripts/rechnungen/ajax_update_order_status_by_scor.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
@@ -444,17 +507,16 @@ $('.bulkSelectSubmit').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const valBulkSelect = $('#bulkSelectedOption').data('value');
|
||||
console.log(valBulkSelect);
|
||||
|
||||
if (valBulkSelect === 'deleteEntrys') {
|
||||
if (valBulkSelect === 'deleteEntrys' || valBulkSelect === 'payEntrys') {
|
||||
let arrayIds = [];
|
||||
|
||||
$('[class^="row_check_"]').each(function () {
|
||||
$('.rowCheckbox').each(function () {
|
||||
if ($(this).prop('checked')) {
|
||||
arrayIds.push($(this).val());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (Array.isArray(arrayIds) && arrayIds.length) {
|
||||
|
||||
const params = new URLSearchParams();
|
||||
@@ -464,9 +526,10 @@ $('.bulkSelectSubmit').on('click', function (e) {
|
||||
});
|
||||
|
||||
params.append('csrf_token', csrf_token);
|
||||
params.append('action', valBulkSelect);
|
||||
|
||||
|
||||
fetch('/intern/scripts/rechnungen/ajax_delete_order.php', {
|
||||
fetch('/intern/scripts/rechnungen/ajax_update_order_status.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
@@ -493,16 +556,14 @@ $('.bulkSelectSubmit').on('click', function (e) {
|
||||
});
|
||||
|
||||
|
||||
document.querySelectorAll('[id^="check_all_"]').forEach(master => {
|
||||
const programm = master.id.replace("check_all_", "");
|
||||
const checkboxes = document.querySelectorAll(".row_check_" + programm);
|
||||
document.querySelectorAll('.masterCheckbox').forEach(master => {
|
||||
const programm = master.dataset.type;
|
||||
const checkboxes = document.querySelectorAll('.rowCheckbox[data-type="' + programm + '"]');
|
||||
|
||||
// toggle all rows when master is clicked
|
||||
master.addEventListener("change", function() {
|
||||
checkboxes.forEach(cb => cb.checked = master.checked);
|
||||
});
|
||||
|
||||
// update master if all rows are manually checked/unchecked
|
||||
checkboxes.forEach(cb => {
|
||||
cb.addEventListener("change", function() {
|
||||
master.checked = [...checkboxes].every(c => c.checked);
|
||||
@@ -548,65 +609,6 @@ function displayMsg(type, msg) {
|
||||
}, 6500);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.customSelect {
|
||||
position: relative;
|
||||
width: 240px;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
.customSelect > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bulkSelectDiv {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.bulkSelect:focus .selectArrow {
|
||||
rotate: 180deg
|
||||
}
|
||||
|
||||
.selectTrigger {
|
||||
width: 100%;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selectOptions {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
list-style: none;
|
||||
background: #fff;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.selectOptions li {
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selectOptions li:hover,
|
||||
.selectOptions li.selected {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
$(function () {
|
||||
|
||||
@@ -645,4 +647,151 @@ $(function () {
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Funktion, um den Tooltip-Container zu erstellen oder zurückzugeben
|
||||
const getOrCreateTooltip = (chart) => {
|
||||
// Suche nach einem Element mit einer spezifischen Klasse
|
||||
let tooltipEl = chart.canvas.parentNode.querySelector('.chartjs-tooltip');
|
||||
|
||||
if (!tooltipEl) {
|
||||
tooltipEl = document.createElement('div');
|
||||
// Füge eine spezifische Klasse hinzu, damit wir es später leicht finden können
|
||||
tooltipEl.classList.add('chartjs-tooltip');
|
||||
|
||||
// Setze die Basis-Stile
|
||||
tooltipEl.style.background = 'rgba(0, 0, 0, 0.7)';
|
||||
tooltipEl.style.borderRadius = '3px';
|
||||
tooltipEl.style.color = 'white';
|
||||
tooltipEl.style.opacity = 1;
|
||||
tooltipEl.style.pointerEvents = 'none';
|
||||
tooltipEl.style.position = 'absolute';
|
||||
tooltipEl.style.transform = 'translate(-50%, 0)';
|
||||
tooltipEl.style.transition = 'all .1s ease';
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.style.margin = '0px';
|
||||
// Optional: Füge eine Klasse zum Table hinzu, falls du es global stylen möchtest
|
||||
table.classList.add('chartjs-tooltip-table');
|
||||
|
||||
tooltipEl.appendChild(table);
|
||||
chart.canvas.parentNode.appendChild(tooltipEl);
|
||||
}
|
||||
|
||||
return tooltipEl;
|
||||
};
|
||||
|
||||
const externalTooltipHandler = (context) => {
|
||||
const {chart, tooltip} = context;
|
||||
// Verwende die korrigierte Funktion
|
||||
const tooltipEl = getOrCreateTooltip(chart);
|
||||
|
||||
// Verstecken, wenn der Tooltip keine Daten hat
|
||||
if (tooltip.opacity === 0) {
|
||||
tooltipEl.style.opacity = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Text setzen
|
||||
if (tooltip.body) {
|
||||
const titleLines = tooltip.title || [];
|
||||
const bodyLines = tooltip.body.map(b => b.lines);
|
||||
|
||||
const tableHead = document.createElement('thead');
|
||||
|
||||
titleLines.forEach(title => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.style.borderWidth = 0;
|
||||
|
||||
const th = document.createElement('th');
|
||||
th.style.borderWidth = 0;
|
||||
const text = document.createTextNode(title);
|
||||
th.appendChild(text);
|
||||
tr.appendChild(th);
|
||||
tableHead.appendChild(tr);
|
||||
});
|
||||
|
||||
const tableBody = document.createElement('tbody');
|
||||
bodyLines.forEach((body, i) => {
|
||||
const colors = tooltip.labelColors[i];
|
||||
|
||||
const span = document.createElement('span');
|
||||
span.style.background = colors.backgroundColor;
|
||||
span.style.borderColor = colors.borderColor;
|
||||
span.style.borderWidth = '2px';
|
||||
span.style.marginRight = '10px';
|
||||
span.style.height = '10px';
|
||||
span.style.width = '10px';
|
||||
span.style.display = 'inline-block';
|
||||
|
||||
const tr = document.createElement('tr');
|
||||
tr.style.backgroundColor = 'inherit';
|
||||
tr.style.borderWidth = 0;
|
||||
|
||||
const td = document.createElement('td');
|
||||
td.style.borderWidth = 0;
|
||||
|
||||
const text = document.createTextNode(body);
|
||||
td.appendChild(span);
|
||||
td.appendChild(text);
|
||||
tr.appendChild(td);
|
||||
tableBody.appendChild(tr);
|
||||
});
|
||||
|
||||
const tableRoot = tooltipEl.querySelector('table');
|
||||
|
||||
// Alte Inhalte entfernen
|
||||
while (tableRoot.firstChild) {
|
||||
tableRoot.firstChild.remove();
|
||||
}
|
||||
|
||||
// Neue Inhalte hinzufügen
|
||||
tableRoot.appendChild(tableHead);
|
||||
tableRoot.appendChild(tableBody);
|
||||
}
|
||||
|
||||
// Position berechnen
|
||||
const {offsetLeft: positionX, offsetTop: positionY} = chart.canvas;
|
||||
|
||||
// Tooltip anzeigen, positionieren und Stile setzen
|
||||
tooltipEl.style.opacity = 1;
|
||||
tooltipEl.style.left = positionX + tooltip.caretX + 'px';
|
||||
tooltipEl.style.top = positionY + tooltip.caretY + 'px';
|
||||
tooltipEl.style.font = tooltip.options.bodyFont.string;
|
||||
tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
|
||||
};
|
||||
|
||||
const ctx = document.getElementById('rechnungenOverviewChart').getContext('2d');
|
||||
new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['Pendant', 'Bezahlt'],
|
||||
datasets: [{
|
||||
// Die Daten bleiben hier als Zahlen (z.B. 150, 200)
|
||||
data: ["<?= $totalOrderVolumeArray[1] ?? 0 ?>", "<?= $totalOrderVolumeArray[2] ?? 0 ?>"],
|
||||
backgroundColor: ['#36a2eb', '#4bc0c0']
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false, // Standard-Tooltip deaktivieren
|
||||
external: externalTooltipHandler, // Ihren Handler verwenden
|
||||
callbacks: {
|
||||
// Diese Funktion wird aufgerufen, um den Text für jeden Datensatz im Tooltip zu formatieren
|
||||
label: function(context) {
|
||||
|
||||
// Der Wert (context.raw) wird als Zahl genommen, mit "CHF" versehen und gerundet
|
||||
const value = context.raw;
|
||||
let label = 'CHF ' + value;
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user