Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8783f97a09 | |||
| 43e09b41f1 | |||
| 84257dc289 |
+4
-1
@@ -3828,7 +3828,10 @@ def api_item_detail(item_id):
|
||||
"""
|
||||
|
||||
client.close()
|
||||
return detail_html, 200
|
||||
return jsonify({
|
||||
'html': detail_html,
|
||||
'images': item.get('Images', item.get('Bilder', []))
|
||||
}), 200
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error fetching item detail: {e}")
|
||||
return jsonify({'error': 'An error occurred while fetching the item detail'}), 500
|
||||
|
||||
@@ -135,21 +135,6 @@
|
||||
.library-scan-status.warn { color: #9a6700; }
|
||||
.library-scan-status.error { color: #b42318; }
|
||||
|
||||
.library-scan-reader-wrap {
|
||||
display: none;
|
||||
margin-top: 12px;
|
||||
max-width: 460px;
|
||||
background: var(--ui-surface);
|
||||
border: 1px solid #d9dde4;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.library-scan-reader {
|
||||
width: 100%;
|
||||
min-height: 280px;
|
||||
}
|
||||
|
||||
/* Filters */
|
||||
.library-filter-toggle-btn {
|
||||
padding: 10px 16px;
|
||||
@@ -431,6 +416,40 @@
|
||||
|
||||
.library-scan-reader-wrap { max-width: 100%; }
|
||||
}
|
||||
.library-scan-reader-wrap {
|
||||
display: none;
|
||||
margin-top: 15px;
|
||||
max-width: 640px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: #000;
|
||||
border: 1px solid #d9dde4;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.library-scan-reader {
|
||||
width: 100%;
|
||||
min-height: 280px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.library-scan-reader video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.library-scan-reader canvas.drawing,
|
||||
.library-scan-reader canvas.drawingBuffer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="library-table-container" id="libraryTableContainer" data-can-edit="{{ 1 if current_permissions.actions.get('can_edit', False) else 0 }}">
|
||||
@@ -457,7 +476,6 @@
|
||||
🔍 Filter
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="library-scan-controls">
|
||||
<select id="scanModeSelect" aria-label="Scan-Modus">
|
||||
<option value="card_only">Nur Ausweis erfassen</option>
|
||||
@@ -475,6 +493,10 @@
|
||||
</label>
|
||||
<button id="manualActionBtn" class="button" type="button" style="margin-left:6px; background:#4f46e5; color:white;">Code verarbeiten</button>
|
||||
</div>
|
||||
<div class="library-scan-reader-wrap" id="scanReaderWrap" style="display: none; margin-top: 15px;">
|
||||
<div class="library-scan-reader" style="width: 100%; max-width: 640px; margin: 0 auto; overflow: hidden; border-radius: 8px; border: 2px solid #ccc;">
|
||||
</div>
|
||||
</div>
|
||||
<div id="filterPanel" class="library-filter-panel">
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
@@ -1309,51 +1331,29 @@
|
||||
detailContent.innerHTML = '<p>Lade Details...</p>';
|
||||
detailModal.style.display = 'flex';
|
||||
|
||||
// Sicherer Zugriff auf das Item mit Fallback
|
||||
const item = libraryItems.find(i => i._id === itemId);
|
||||
let mediaHtml = '';
|
||||
|
||||
// Robuste Prüfung: Wir testen gängige Benennungen aus deinem Backend
|
||||
const imageArray = item.Images || item.Bilder || item.images;
|
||||
if (item) {
|
||||
// Prüfe gängige Array-Namen aus dem Backend
|
||||
const imageArray = item.Images || item.Bilder || item.images;
|
||||
|
||||
if (item && Array.isArray(imageArray) && imageArray.length > 0) {
|
||||
const imagesHtml = imageArray.map((image, index) => {
|
||||
if (Array.isArray(imageArray) && imageArray.length > 0) {
|
||||
const imagesHtml = imageArray.map(image => {
|
||||
// Direkter, robuster Pfad zur Upload-Route
|
||||
const imageSrc = image.startsWith('/uploads/') || image.startsWith('http')
|
||||
? image
|
||||
: `/uploads/${image}`;
|
||||
|
||||
// Dein neuer Code für die exakte Routen-Generierung
|
||||
const imageSrc = image.startsWith('/uploads/') || image.startsWith('http') ?
|
||||
image :
|
||||
`{{ url_for('uploaded_file', filename='') }}${image}`;
|
||||
return `<img src="${imageSrc}" alt="${escapeHtml(item.Name || 'Medium')}" class="item-image" style="width: 120px; height: 120px; object-fit: cover; border-radius: 8px; border: 1px solid #ddd; margin-right: 15px; margin-bottom: 15px;">`;
|
||||
}).join('');
|
||||
|
||||
const thumbnailInfo = item.ThumbnailInfo && item.ThumbnailInfo[index];
|
||||
const isVideo = isVideoFile(image);
|
||||
|
||||
if (isVideo) {
|
||||
const videoSrc = thumbnailInfo && thumbnailInfo.has_thumbnail
|
||||
? thumbnailInfo.thumbnail_url
|
||||
: imageSrc;
|
||||
|
||||
if (thumbnailInfo && thumbnailInfo.has_thumbnail) {
|
||||
return `
|
||||
<div class="video-container" style="position: relative; width: 120px; height: 120px; display: inline-block; margin-right: 15px; margin-bottom: 15px;">
|
||||
<img src="${videoSrc}" alt="${escapeHtml(item.Name || 'Medium')}" class="item-image" style="width: 100%; height: 100%; object-fit: cover; border-radius: 8px; border: 1px solid #ddd;">
|
||||
<div class="video-preview-overlay" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; background: rgba(0,0,0,0.6); border-radius: 50%; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; font-size: 16px;">
|
||||
▶
|
||||
</div>
|
||||
</div>`;
|
||||
} else {
|
||||
return `<div style="width: 120px; height: 120px; background: #333; color: #fff; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; margin-right: 15px; margin-bottom: 15px;">VIDEO</div>`;
|
||||
}
|
||||
} else {
|
||||
const imageSrcFinal = thumbnailInfo && thumbnailInfo.has_thumbnail
|
||||
? thumbnailInfo.thumbnail_url
|
||||
: imageSrc;
|
||||
|
||||
return `<img src="${imageSrcFinal}" alt="${escapeHtml(item.Name || 'Medium')}" class="item-image" style="width: 120px; height: 120px; object-fit: cover; border-radius: 8px; border: 1px solid #ddd; margin-right: 15px; margin-bottom: 15px;">`;
|
||||
}
|
||||
}).join('');
|
||||
|
||||
mediaHtml = `<div class="detail-gallery-container" style="margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #eee; display: flex; flex-wrap: wrap;">${imagesHtml}</div>`;
|
||||
mediaHtml = `<div class="detail-gallery-container" style="margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #eee; display: flex; flex-wrap: wrap;">${imagesHtml}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
// Zusätzliche Details vom Backend laden
|
||||
fetch(`/api/item_detail/${itemId}`)
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
@@ -1368,7 +1368,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Closes the modal via the 'x' button
|
||||
// Schließt das Modal über den 'x'-Button
|
||||
function closeDetailModal() {
|
||||
document.getElementById('detailModal').style.display = 'none';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user