📝 "🐛 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 totalRequests = 0;
|
||||
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
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@ -641,29 +647,24 @@ async function loadGuestRequests() {
|
||||
|
||||
const params = new URLSearchParams({
|
||||
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') params.append('urgent', urgent);
|
||||
if (sort) params.append('sort', sort);
|
||||
if (search) params.append('search', search);
|
||||
if (urgent !== 'all') {
|
||||
params.append('urgent', urgent === 'urgent');
|
||||
}
|
||||
|
||||
const response = await fetch(`/api/admin/guest-requests?${params}`);
|
||||
|
||||
// Enhanced error handling for JSON parsing
|
||||
let data;
|
||||
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}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
currentRequests = data.requests;
|
||||
totalRequests = data.total;
|
||||
@ -671,11 +672,15 @@ async function loadGuestRequests() {
|
||||
renderRequestsTable(data.requests);
|
||||
updatePagination();
|
||||
} 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) {
|
||||
console.error('Fehler beim Laden der Anträge:', error);
|
||||
showNotification('Fehler beim Laden der Anträge: ' + error.message, 'error');
|
||||
console.error('Fehler beim Laden der Gastanträge:', error);
|
||||
showNotification(`Fehler beim Laden der Gastanträge: ${error.message}`, 'error');
|
||||
|
||||
// Zeige leere Tabelle bei Fehler
|
||||
renderRequestsTable([]);
|
||||
updateStatistics({});
|
||||
} finally {
|
||||
showLoading(false);
|
||||
}
|
||||
@ -687,6 +692,8 @@ async function loadAvailablePrinters() {
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
allPrinters = data.printers;
|
||||
|
||||
const select = document.getElementById('assignedPrinter');
|
||||
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-copy ml-2 mr-1"></i>${request.copies || 1} Kopien
|
||||
</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 class="px-6 py-4">
|
||||
<span class="status-badge status-${request.status}">
|
||||
${getStatusIcon(request.status)} ${getStatusText(request.status)}
|
||||
</span>
|
||||
${request.status === 'pending' ? `
|
||||
${request.status === 'pending' && showInlineActions ? `
|
||||
<div id="inline-actions-${request.id}" class="mt-2 space-y-2">
|
||||
<div class="flex space-x-2">
|
||||
<button onclick="showInlineApproval(${request.id})"
|
||||
@ -791,8 +799,10 @@ function createRequestRow(request) {
|
||||
</div>
|
||||
|
||||
<!-- Inline Approval Form -->
|
||||
<div id="approval-form-${request.id}" class="hidden bg-green-50 border border-green-200 rounded p-3">
|
||||
<h5 class="text-sm font-medium text-green-800 mb-2">Antrag genehmigen</h5>
|
||||
<div id="approval-form-${request.id}" class="hidden inline-approval-form form-section">
|
||||
<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"
|
||||
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>
|
||||
@ -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">
|
||||
<option value="">Drucker auswählen (optional)</option>
|
||||
</select>
|
||||
<div class="flex justify-end space-x-2 mt-2">
|
||||
<div class="form-actions">
|
||||
<button onclick="hideInlineApproval(${request.id})"
|
||||
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
|
||||
Abbrechen
|
||||
class="btn-cancel inline-action-btn">
|
||||
<i class="fas fa-times mr-1"></i>Abbrechen
|
||||
</button>
|
||||
<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
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Inline Rejection Form -->
|
||||
<div id="rejection-form-${request.id}" class="hidden bg-red-50 border border-red-200 rounded p-3">
|
||||
<h5 class="text-sm font-medium text-red-800 mb-2">Antrag ablehnen</h5>
|
||||
<div id="rejection-form-${request.id}" class="hidden inline-rejection-form form-section">
|
||||
<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
|
||||
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>
|
||||
<div class="flex justify-end space-x-2 mt-2">
|
||||
<div class="form-actions">
|
||||
<button onclick="hideInlineRejection(${request.id})"
|
||||
class="px-2 py-1 text-xs border border-gray-300 rounded text-gray-600 hover:bg-gray-50">
|
||||
Abbrechen
|
||||
class="btn-cancel inline-action-btn">
|
||||
<i class="fas fa-times mr-1"></i>Abbrechen
|
||||
</button>
|
||||
<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
|
||||
</button>
|
||||
</div>
|
||||
@ -842,7 +854,7 @@ function createRequestRow(request) {
|
||||
class="action-button btn-view" title="Details anzeigen">
|
||||
<i class="fas fa-eye"></i> Details
|
||||
</button>
|
||||
${request.status !== 'pending' ? `
|
||||
${request.status !== 'pending' && showInlineActions ? `
|
||||
<button onclick="deleteRequest(${request.id})"
|
||||
class="action-button bg-gray-500 text-white hover:bg-gray-600" title="Löschen">
|
||||
<i class="fas fa-trash"></i>
|
||||
@ -1262,6 +1274,13 @@ async function submitInlineApproval(requestId) {
|
||||
}
|
||||
|
||||
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`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -1271,29 +1290,29 @@ async function submitInlineApproval(requestId) {
|
||||
body: JSON.stringify(requestBody)
|
||||
});
|
||||
|
||||
// Enhanced error handling for JSON parsing
|
||||
let data;
|
||||
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}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showNotification(`Antrag erfolgreich genehmigt! OTP-Code: ${data.otp_code}`, 'success');
|
||||
hideInlineApproval(requestId);
|
||||
loadGuestRequests(); // Reload table
|
||||
} else {
|
||||
showNotification(`Fehler beim Genehmigen: ${data.message || 'Unbekannter Fehler'}`, 'error');
|
||||
throw new Error(data.message || 'Unbekannter Fehler beim Genehmigen');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Genehmigen:', 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 {
|
||||
// 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`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -1315,29 +1341,29 @@ async function submitInlineRejection(requestId) {
|
||||
body: JSON.stringify({ reason })
|
||||
});
|
||||
|
||||
// Enhanced error handling for JSON parsing
|
||||
let data;
|
||||
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}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showNotification('Antrag erfolgreich abgelehnt', 'success');
|
||||
hideInlineRejection(requestId);
|
||||
loadGuestRequests(); // Reload table
|
||||
} else {
|
||||
showNotification(`Fehler beim Ablehnen: ${data.message || 'Unbekannter Fehler'}`, 'error');
|
||||
throw new Error(data.message || 'Unbekannter Fehler beim Ablehnen');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Ablehnen:', 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