V1.0
This commit is contained in:
@@ -234,6 +234,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<h3 style="margin-bottom: 10px;">Check-in URL-Konfiguration</h3>
|
||||
<p style="margin-bottom: 15px; color: #666;">Definieren Sie die Basis-URL für alle Check-in und Check-out URLs. Diese URL wird vor <code>/api</code> verwendet. Beispiel: https://example.com:3334</p>
|
||||
<label for="checkinRootUrl">Check-in Root URL</label>
|
||||
<input type="text" id="checkinRootUrl" name="checkin_root_url" class="form-control" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;" placeholder="https://example.com:3334" value="<%= (typeof options !== 'undefined' && options && options.checkin_root_url) ? options.checkin_root_url : '' %>">
|
||||
<small style="color: #666; display: block; margin-top: 5px;">Lassen Sie dieses Feld leer, um die URL automatisch aus der aktuellen Seite zu generieren.</small>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Optionen speichern</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -289,7 +297,7 @@
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="ldapUsernameAttr">Username-Attribut</label>
|
||||
<input type="text" id="ldapUsernameAttr" name="username_attribute" placeholder="cn" value="cn">
|
||||
<input type="text" id="ldapUsernameAttr" name="username_attribute" placeholder="sAMAccountName" value="sAMAccountName">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
@@ -99,28 +99,59 @@
|
||||
Automatische Zeiterfassung
|
||||
</h3>
|
||||
<div id="timeCaptureContent" style="display: none; margin-top: 15px;">
|
||||
<!-- URL-Erfassung -->
|
||||
<!-- Interne URLs -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h4 style="font-size: 13px; margin-bottom: 10px; color: #555; display: flex; align-items: center; gap: 5px;">
|
||||
Zeiterfassung per URL
|
||||
<span class="help-icon" onclick="showHelpModal('url-help')" style="cursor: pointer; color: #3498db; font-size: 14px; font-weight: bold; width: 18px; height: 18px; border-radius: 50%; background: #e8f4f8; display: inline-flex; align-items: center; justify-content: center; line-height: 1;">?</span>
|
||||
<h4 style="font-size: 13px; margin-bottom: 10px; color: #555; cursor: pointer; user-select: none; display: flex; align-items: center; gap: 8px;" onclick="toggleInternalUrls()">
|
||||
<span class="toggle-icon-internal-urls" style="display: inline-block; transition: transform 0.3s; font-size: 10px;">▶</span>
|
||||
Interne URLs
|
||||
<span class="help-icon" onclick="event.stopPropagation(); showHelpModal('url-help')" style="cursor: pointer; color: #3498db; font-size: 14px; font-weight: bold; width: 18px; height: 18px; border-radius: 50%; background: #e8f4f8; display: inline-flex; align-items: center; justify-content: center; line-height: 1; margin-left: auto;">?</span>
|
||||
</h4>
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-in URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkinUrl" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkinUrl')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
<div id="internalUrlsContent" style="display: none; margin-top: 10px;">
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-in URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkinUrlInternal" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkinUrlInternal')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-out URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkoutUrlInternal" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkoutUrlInternal')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 12px;">
|
||||
<a href="/api/dashboard/qr-pdf/internal" class="btn btn-sm btn-secondary" style="padding: 8px 12px; text-decoration: none; display: inline-block;" download>QR-Code-PDF herunterladen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-out URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkoutUrl" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkoutUrl')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
</div>
|
||||
|
||||
<!-- Externe URLs -->
|
||||
<div id="externalUrlsSection" style="margin-bottom: 20px; display: none;">
|
||||
<h4 style="font-size: 13px; margin-bottom: 10px; color: #555; cursor: pointer; user-select: none; display: flex; align-items: center; gap: 8px;" onclick="toggleExternalUrls()">
|
||||
<span class="toggle-icon-external-urls" style="display: inline-block; transition: transform 0.3s; font-size: 10px;">▶</span>
|
||||
Externe URLs
|
||||
<span class="help-icon" onclick="event.stopPropagation(); showHelpModal('url-help')" style="cursor: pointer; color: #3498db; font-size: 14px; font-weight: bold; width: 18px; height: 18px; border-radius: 50%; background: #e8f4f8; display: inline-flex; align-items: center; justify-content: center; line-height: 1; margin-left: auto;">?</span>
|
||||
</h4>
|
||||
<div id="externalUrlsContent" style="display: none; margin-top: 10px;">
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-in URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkinUrlExternal" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkinUrlExternal')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom: 15px;">
|
||||
<label style="font-size: 12px; color: #666; margin-bottom: 5px;">Check-out URL</label>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<input type="text" id="checkoutUrlExternal" readonly style="flex: 1; padding: 8px; font-size: 11px; border: 1px solid #ddd; border-radius: 4px; background: #f8f9fa;">
|
||||
<button onclick="copyToClipboard('checkoutUrlExternal')" class="btn btn-sm btn-secondary" style="padding: 8px 12px;">Kopieren</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 12px;">
|
||||
<a href="/api/dashboard/qr-pdf/external" class="btn btn-sm btn-secondary" style="padding: 8px 12px; text-decoration: none; display: inline-block;" download>QR-Code-PDF herunterladen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 12px;">
|
||||
<a href="/api/dashboard/qr-pdf" class="btn btn-sm btn-secondary" style="padding: 8px 12px; text-decoration: none; display: inline-block;" download>QR-Code-PDF herunterladen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -180,6 +211,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Interne URLs ein-/ausklappen
|
||||
function toggleInternalUrls() {
|
||||
const content = document.getElementById('internalUrlsContent');
|
||||
const icon = document.querySelector('.toggle-icon-internal-urls');
|
||||
|
||||
if (content && icon) {
|
||||
if (content.style.display === 'none') {
|
||||
content.style.display = 'block';
|
||||
icon.style.transform = 'rotate(90deg)';
|
||||
} else {
|
||||
content.style.display = 'none';
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Externe URLs ein-/ausklappen
|
||||
function toggleExternalUrls() {
|
||||
const content = document.getElementById('externalUrlsContent');
|
||||
const icon = document.querySelector('.toggle-icon-external-urls');
|
||||
|
||||
if (content && icon) {
|
||||
if (content.style.display === 'none') {
|
||||
content.style.display = 'block';
|
||||
icon.style.transform = 'rotate(90deg)';
|
||||
} else {
|
||||
content.style.display = 'none';
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// URL-Kopier-Funktion
|
||||
function copyToClipboard(inputId) {
|
||||
const input = document.getElementById(inputId);
|
||||
@@ -201,24 +264,56 @@
|
||||
}
|
||||
|
||||
// URLs mit aktueller Domain aktualisieren (Port 3334 für Check-in)
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', async function() {
|
||||
const userId = '<%= user.id %>';
|
||||
|
||||
// Interne URLs: Konstruiere aus window.location.origin (Port 3334 für Check-in)
|
||||
const baseUrl = window.location.origin;
|
||||
// Check-in URLs verwenden Port 3334
|
||||
// Ersetze Port in URL oder füge Port hinzu falls nicht vorhanden
|
||||
let checkinBaseUrl;
|
||||
let internalBaseUrl;
|
||||
if (baseUrl.match(/:\d+$/)) {
|
||||
// Port vorhanden - ersetze ihn
|
||||
checkinBaseUrl = baseUrl.replace(/:\d+$/, ':3334');
|
||||
internalBaseUrl = baseUrl.replace(/:\d+$/, ':3334');
|
||||
} else {
|
||||
// Kein Port - füge Port hinzu
|
||||
const url = new URL(baseUrl);
|
||||
checkinBaseUrl = `${url.protocol}//${url.hostname}:3334`;
|
||||
internalBaseUrl = `${url.protocol}//${url.hostname}:3334`;
|
||||
}
|
||||
|
||||
// Setze interne URLs
|
||||
const checkinInputInternal = document.getElementById('checkinUrlInternal');
|
||||
const checkoutInputInternal = document.getElementById('checkoutUrlInternal');
|
||||
if (checkinInputInternal) checkinInputInternal.value = `${internalBaseUrl}/api/checkin/${userId}`;
|
||||
if (checkoutInputInternal) checkoutInputInternal.value = `${internalBaseUrl}/api/checkout/${userId}`;
|
||||
|
||||
// Externe URLs: Versuche Root URL von API zu laden
|
||||
let externalBaseUrl = null;
|
||||
try {
|
||||
const response = await fetch('/api/checkin-root-url');
|
||||
const result = await response.json();
|
||||
if (result.root_url && result.root_url.trim() !== '') {
|
||||
externalBaseUrl = result.root_url.trim();
|
||||
// Stelle sicher, dass kein trailing slash vorhanden ist
|
||||
externalBaseUrl = externalBaseUrl.replace(/\/+$/, '');
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Fehler beim Laden der externen Root URL:', error);
|
||||
}
|
||||
|
||||
// Zeige externe Sektion nur an, wenn Root URL konfiguriert ist
|
||||
const externalSection = document.getElementById('externalUrlsSection');
|
||||
if (externalBaseUrl) {
|
||||
// Setze externe URLs
|
||||
const checkinInputExternal = document.getElementById('checkinUrlExternal');
|
||||
const checkoutInputExternal = document.getElementById('checkoutUrlExternal');
|
||||
if (checkinInputExternal) checkinInputExternal.value = `${externalBaseUrl}/api/checkin/${userId}`;
|
||||
if (checkoutInputExternal) checkoutInputExternal.value = `${externalBaseUrl}/api/checkout/${userId}`;
|
||||
|
||||
// Zeige externe Sektion an
|
||||
if (externalSection) externalSection.style.display = 'block';
|
||||
} else {
|
||||
// Verstecke externe Sektion
|
||||
if (externalSection) externalSection.style.display = 'none';
|
||||
}
|
||||
const checkinInput = document.getElementById('checkinUrl');
|
||||
const checkoutInput = document.getElementById('checkoutUrl');
|
||||
if (checkinInput) checkinInput.value = `${checkinBaseUrl}/api/checkin/${userId}`;
|
||||
if (checkoutInput) checkoutInput.value = `${checkinBaseUrl}/api/checkout/${userId}`;
|
||||
|
||||
// Rollenwechsel-Handler
|
||||
const roleSwitcher = document.getElementById('roleSwitcher');
|
||||
|
||||
Reference in New Issue
Block a user