📝 "🐛 Backend update: Refactored database connection in myp.db
This commit is contained in:
parent
c48d586af2
commit
37cd332d67
Binary file not shown.
@ -558,6 +558,12 @@ let currentPage = 0;
|
|||||||
let pageSize = 20;
|
let pageSize = 20;
|
||||||
let totalRequests = 0;
|
let totalRequests = 0;
|
||||||
let currentRequestId = null;
|
let currentRequestId = null;
|
||||||
|
let allPrinters = [];
|
||||||
|
|
||||||
|
// Prüfung der Admin-Berechtigung - zeige Inline-Aktionen nur für Admins
|
||||||
|
const userIsAdmin = {{ current_user.is_admin|tojson if current_user.is_authenticated else 'false' }};
|
||||||
|
const userCanApprove = {{ (current_user.permissions and current_user.permissions.can_approve_jobs)|tojson if current_user.is_authenticated and current_user.permissions else 'false' }};
|
||||||
|
const showInlineActions = userIsAdmin || userCanApprove;
|
||||||
|
|
||||||
// Initialisierung
|
// Initialisierung
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
@ -641,29 +647,24 @@ async function loadGuestRequests() {
|
|||||||
|
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
page_size: pageSize
|
page_size: pageSize,
|
||||||
|
status: status !== 'all' ? status : '',
|
||||||
|
sort: sort,
|
||||||
|
search: search
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status !== 'all') params.append('status', status);
|
if (urgent !== 'all') {
|
||||||
if (urgent !== 'all') params.append('urgent', urgent);
|
params.append('urgent', urgent === 'urgent');
|
||||||
if (sort) params.append('sort', sort);
|
}
|
||||||
if (search) params.append('search', search);
|
|
||||||
|
|
||||||
const response = await fetch(`/api/admin/guest-requests?${params}`);
|
const response = await fetch(`/api/admin/guest-requests?${params}`);
|
||||||
|
|
||||||
// Enhanced error handling for JSON parsing
|
if (!response.ok) {
|
||||||
let data;
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
try {
|
|
||||||
const text = await response.text();
|
|
||||||
if (!text.trim()) {
|
|
||||||
throw new Error('Leere Antwort vom Server');
|
|
||||||
}
|
|
||||||
data = JSON.parse(text);
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('JSON Parse Error:', parseError, 'Response text:', text);
|
|
||||||
throw new Error(`JSON-Parsing-Fehler beim Laden der Anträge: ${parseError.message}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
currentRequests = data.requests;
|
currentRequests = data.requests;
|
||||||
totalRequests = data.total;
|
totalRequests = data.total;
|
||||||
@ -671,11 +672,15 @@ async function loadGuestRequests() {
|
|||||||
renderRequestsTable(data.requests);
|
renderRequestsTable(data.requests);
|
||||||
updatePagination();
|
updatePagination();
|
||||||
} else {
|
} else {
|
||||||
showNotification('Fehler beim Laden der Anträge: ' + (data.message || 'Unbekannter Fehler'), 'error');
|
throw new Error(data.message || 'Unbekannter Fehler beim Laden der Daten');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Laden der Anträge:', error);
|
console.error('Fehler beim Laden der Gastanträge:', error);
|
||||||
showNotification('Fehler beim Laden der Anträge: ' + error.message, 'error');
|
showNotification(`Fehler beim Laden der Gastanträge: ${error.message}`, 'error');
|
||||||
|
|
||||||
|
// Zeige leere Tabelle bei Fehler
|
||||||
|
renderRequestsTable([]);
|
||||||
|
updateStatistics({});
|
||||||
} finally {
|
} finally {
|
||||||
showLoading(false);
|
showLoading(false);
|
||||||
}
|
}
|
||||||
@ -687,6 +692,8 @@ async function loadAvailablePrinters() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
|
allPrinters = data.printers;
|
||||||
|
|
||||||
const select = document.getElementById('assignedPrinter');
|
const select = document.getElementById('assignedPrinter');
|
||||||
select.innerHTML = '<option value="">Kein Drucker zugewiesen</option>';
|
select.innerHTML = '<option value="">Kein Drucker zugewiesen</option>';
|
||||||
|
|
||||||
@ -772,12 +779,13 @@ function createRequestRow(request) {
|
|||||||
<i class="fas fa-clock mr-1"></i>${request.duration_minutes || 0} Min,
|
<i class="fas fa-clock mr-1"></i>${request.duration_minutes || 0} Min,
|
||||||
<i class="fas fa-copy ml-2 mr-1"></i>${request.copies || 1} Kopien
|
<i class="fas fa-copy ml-2 mr-1"></i>${request.copies || 1} Kopien
|
||||||
</div>
|
</div>
|
||||||
|
${request.reason ? `<div class="text-xs text-gray-400 mt-1">${escapeHtml(request.reason.substring(0, 100))}${request.reason.length > 100 ? '...' : ''}</div>` : ''}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<span class="status-badge status-${request.status}">
|
<span class="status-badge status-${request.status}">
|
||||||
${getStatusIcon(request.status)} ${getStatusText(request.status)}
|
${getStatusIcon(request.status)} ${getStatusText(request.status)}
|
||||||
</span>
|
</span>
|
||||||
${request.status === 'pending' ? `
|
${request.status === 'pending' && showInlineActions ? `
|
||||||
<div id="inline-actions-${request.id}" class="mt-2 space-y-2">
|
<div id="inline-actions-${request.id}" class="mt-2 space-y-2">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<button onclick="showInlineApproval(${request.id})"
|
<button onclick="showInlineApproval(${request.id})"
|
||||||
@ -791,8 +799,10 @@ function createRequestRow(request) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Inline Approval Form -->
|
<!-- Inline Approval Form -->
|
||||||
<div id="approval-form-${request.id}" class="hidden bg-green-50 border border-green-200 rounded p-3">
|
<div id="approval-form-${request.id}" class="hidden inline-approval-form form-section">
|
||||||
<h5 class="text-sm font-medium text-green-800 mb-2">Antrag genehmigen</h5>
|
<h5 class="text-sm font-medium text-green-800 mb-2">
|
||||||
|
<i class="fas fa-check-circle mr-1"></i>Antrag genehmigen
|
||||||
|
</h5>
|
||||||
<textarea id="approval-notes-${request.id}" rows="2"
|
<textarea id="approval-notes-${request.id}" rows="2"
|
||||||
class="w-full text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400"
|
class="w-full text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400"
|
||||||
placeholder="Optionale Genehmigungsnotizen..."></textarea>
|
placeholder="Optionale Genehmigungsnotizen..."></textarea>
|
||||||
@ -800,31 +810,33 @@ function createRequestRow(request) {
|
|||||||
class="w-full mt-1 text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400">
|
class="w-full mt-1 text-xs border border-green-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-green-400">
|
||||||
<option value="">Drucker auswählen (optional)</option>
|
<option value="">Drucker auswählen (optional)</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="flex justify-end space-x-2 mt-2">
|
<div class="form-actions">
|
||||||
<button onclick="hideInlineApproval(${request.id})"
|
<button onclick="hideInlineApproval(${request.id})"
|
||||||
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
|
class="btn-cancel inline-action-btn">
|
||||||
Abbrechen
|
<i class="fas fa-times mr-1"></i>Abbrechen
|
||||||
</button>
|
</button>
|
||||||
<button onclick="submitInlineApproval(${request.id})"
|
<button onclick="submitInlineApproval(${request.id})"
|
||||||
class="px-2 py-1 text-xs bg-green-600 text-white rounded hover:bg-green-700">
|
class="btn-submit inline-action-btn inline-approve-btn">
|
||||||
<i class="fas fa-check mr-1"></i>Genehmigen
|
<i class="fas fa-check mr-1"></i>Genehmigen
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Inline Rejection Form -->
|
<!-- Inline Rejection Form -->
|
||||||
<div id="rejection-form-${request.id}" class="hidden bg-red-50 border border-red-200 rounded p-3">
|
<div id="rejection-form-${request.id}" class="hidden inline-rejection-form form-section">
|
||||||
<h5 class="text-sm font-medium text-red-800 mb-2">Antrag ablehnen</h5>
|
<h5 class="text-sm font-medium text-red-800 mb-2">
|
||||||
|
<i class="fas fa-times-circle mr-1"></i>Antrag ablehnen
|
||||||
|
</h5>
|
||||||
<textarea id="rejection-reason-${request.id}" rows="2" required
|
<textarea id="rejection-reason-${request.id}" rows="2" required
|
||||||
class="w-full text-xs border border-red-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-red-400"
|
class="w-full text-xs border border-red-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-red-400"
|
||||||
placeholder="Ablehnungsgrund (erforderlich)..."></textarea>
|
placeholder="Ablehnungsgrund (erforderlich)..."></textarea>
|
||||||
<div class="flex justify-end space-x-2 mt-2">
|
<div class="form-actions">
|
||||||
<button onclick="hideInlineRejection(${request.id})"
|
<button onclick="hideInlineRejection(${request.id})"
|
||||||
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
|
class="btn-cancel inline-action-btn">
|
||||||
Abbrechen
|
<i class="fas fa-times mr-1"></i>Abbrechen
|
||||||
</button>
|
</button>
|
||||||
<button onclick="submitInlineRejection(${request.id})"
|
<button onclick="submitInlineRejection(${request.id})"
|
||||||
class="px-2 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700">
|
class="btn-submit inline-action-btn inline-reject-btn">
|
||||||
<i class="fas fa-times mr-1"></i>Ablehnen
|
<i class="fas fa-times mr-1"></i>Ablehnen
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -842,7 +854,7 @@ function createRequestRow(request) {
|
|||||||
class="action-button btn-view" title="Details anzeigen">
|
class="action-button btn-view" title="Details anzeigen">
|
||||||
<i class="fas fa-eye"></i> Details
|
<i class="fas fa-eye"></i> Details
|
||||||
</button>
|
</button>
|
||||||
${request.status !== 'pending' ? `
|
${request.status !== 'pending' && showInlineActions ? `
|
||||||
<button onclick="deleteRequest(${request.id})"
|
<button onclick="deleteRequest(${request.id})"
|
||||||
class="action-button bg-gray-500 text-white hover:bg-gray-600" title="Löschen">
|
class="action-button bg-gray-500 text-white hover:bg-gray-600" title="Löschen">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
@ -1262,6 +1274,13 @@ async function submitInlineApproval(requestId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Loading-Zustand anzeigen
|
||||||
|
const submitBtn = document.querySelector(`#approval-form-${requestId} .inline-approve-btn`);
|
||||||
|
const originalText = submitBtn.innerHTML;
|
||||||
|
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Wird bearbeitet...';
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
|
// KORRIGIERTE API-URL
|
||||||
const response = await fetch(`/api/guest-requests/${requestId}/approve`, {
|
const response = await fetch(`/api/guest-requests/${requestId}/approve`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -1271,29 +1290,29 @@ async function submitInlineApproval(requestId) {
|
|||||||
body: JSON.stringify(requestBody)
|
body: JSON.stringify(requestBody)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enhanced error handling for JSON parsing
|
if (!response.ok) {
|
||||||
let data;
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
try {
|
|
||||||
const text = await response.text();
|
|
||||||
if (!text.trim()) {
|
|
||||||
throw new Error('Leere Antwort vom Server');
|
|
||||||
}
|
|
||||||
data = JSON.parse(text);
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('JSON Parse Error:', parseError, 'Response text:', await response.text());
|
|
||||||
throw new Error(`JSON-Parsing-Fehler: ${parseError.message}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
showNotification(`Antrag erfolgreich genehmigt! OTP-Code: ${data.otp_code}`, 'success');
|
showNotification(`Antrag erfolgreich genehmigt! OTP-Code: ${data.otp_code}`, 'success');
|
||||||
hideInlineApproval(requestId);
|
hideInlineApproval(requestId);
|
||||||
loadGuestRequests(); // Reload table
|
loadGuestRequests(); // Reload table
|
||||||
} else {
|
} else {
|
||||||
showNotification(`Fehler beim Genehmigen: ${data.message || 'Unbekannter Fehler'}`, 'error');
|
throw new Error(data.message || 'Unbekannter Fehler beim Genehmigen');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Genehmigen:', error);
|
console.error('Fehler beim Genehmigen:', error);
|
||||||
showNotification(`Fehler beim Genehmigen: ${error.message}`, 'error');
|
showNotification(`Fehler beim Genehmigen: ${error.message}`, 'error');
|
||||||
|
|
||||||
|
// Button-Zustand zurücksetzen
|
||||||
|
const submitBtn = document.querySelector(`#approval-form-${requestId} .inline-approve-btn`);
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.innerHTML = originalText;
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,6 +1325,13 @@ async function submitInlineRejection(requestId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Loading-Zustand anzeigen
|
||||||
|
const submitBtn = document.querySelector(`#rejection-form-${requestId} .inline-reject-btn`);
|
||||||
|
const originalText = submitBtn.innerHTML;
|
||||||
|
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i>Wird bearbeitet...';
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
|
// KORRIGIERTE API-URL
|
||||||
const response = await fetch(`/api/guest-requests/${requestId}/reject`, {
|
const response = await fetch(`/api/guest-requests/${requestId}/reject`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -1315,29 +1341,29 @@ async function submitInlineRejection(requestId) {
|
|||||||
body: JSON.stringify({ reason })
|
body: JSON.stringify({ reason })
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enhanced error handling for JSON parsing
|
if (!response.ok) {
|
||||||
let data;
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
try {
|
|
||||||
const text = await response.text();
|
|
||||||
if (!text.trim()) {
|
|
||||||
throw new Error('Leere Antwort vom Server');
|
|
||||||
}
|
|
||||||
data = JSON.parse(text);
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('JSON Parse Error:', parseError, 'Response text:', await response.text());
|
|
||||||
throw new Error(`JSON-Parsing-Fehler: ${parseError.message}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
showNotification('Antrag erfolgreich abgelehnt', 'success');
|
showNotification('Antrag erfolgreich abgelehnt', 'success');
|
||||||
hideInlineRejection(requestId);
|
hideInlineRejection(requestId);
|
||||||
loadGuestRequests(); // Reload table
|
loadGuestRequests(); // Reload table
|
||||||
} else {
|
} else {
|
||||||
showNotification(`Fehler beim Ablehnen: ${data.message || 'Unbekannter Fehler'}`, 'error');
|
throw new Error(data.message || 'Unbekannter Fehler beim Ablehnen');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Ablehnen:', error);
|
console.error('Fehler beim Ablehnen:', error);
|
||||||
showNotification(`Fehler beim Ablehnen: ${error.message}`, 'error');
|
showNotification(`Fehler beim Ablehnen: ${error.message}`, 'error');
|
||||||
|
|
||||||
|
// Button-Zustand zurücksetzen
|
||||||
|
const submitBtn = document.querySelector(`#rejection-form-${requestId} .inline-reject-btn`);
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.innerHTML = originalText;
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user