Compare commits

..

3 Commits

Author SHA1 Message Date
Aiirondev_dev 8783f97a09 improvements in displaying the Images in the detailed view
Release Inventarsystem / release-docker (push) Successful in 2m15s
2026-08-16 22:19:41 +02:00
Aiirondev_dev 43e09b41f1 Slight change to the Style for the scnaner
Release Inventarsystem / release-docker (push) Successful in 2m16s
2026-08-16 21:23:04 +02:00
Aiirondev_dev 84257dc289 Fix / implementation of the according wrapper for the scanner processing
Release Inventarsystem / release-docker (push) Successful in 2m18s
2026-08-16 21:07:47 +02:00
2 changed files with 58 additions and 55 deletions
+4 -1
View File
@@ -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
+54 -54
View File
@@ -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';
}