add aha blatt parsing
This commit is contained in:
@@ -57,6 +57,8 @@ export default {
|
||||
const showPdfViewer = ref(false);
|
||||
const pdfViewerUrl = ref('');
|
||||
const pdfViewerTitle = ref('');
|
||||
const showImageViewer = ref(false);
|
||||
const imageViewerUrl = ref('');
|
||||
|
||||
// Upload state
|
||||
const uploadDocType = ref('');
|
||||
@@ -631,6 +633,16 @@ export default {
|
||||
showPdfViewer.value = true;
|
||||
};
|
||||
|
||||
// Open image in fullscreen viewer with zoom
|
||||
const openImageViewer = (url) => {
|
||||
imageViewerUrl.value = url;
|
||||
showImageViewer.value = true;
|
||||
};
|
||||
const closeImageViewer = () => {
|
||||
showImageViewer.value = false;
|
||||
imageViewerUrl.value = '';
|
||||
};
|
||||
|
||||
// Initialize
|
||||
onMounted(() => {
|
||||
fetchWorkorders();
|
||||
@@ -697,6 +709,10 @@ export default {
|
||||
callCustomer,
|
||||
handleComplete,
|
||||
openPdfViewer,
|
||||
openImageViewer,
|
||||
closeImageViewer,
|
||||
showImageViewer,
|
||||
imageViewerUrl,
|
||||
handleTouchStart,
|
||||
handleTouchMove,
|
||||
handleTouchEnd,
|
||||
@@ -945,38 +961,95 @@ export default {
|
||||
</svg>
|
||||
</button>
|
||||
<div v-if="expandedCards.technical" class="px-4 pb-4 space-y-3">
|
||||
<!-- Patchposition -->
|
||||
<div v-if="technicalData.patchposition?.equipmentName" class="space-y-2">
|
||||
<div class="text-sm font-medium text-slate-500 dark:text-slate-400">Patchposition</div>
|
||||
<div class="bg-slate-50 dark:bg-slate-700/50 rounded-lg p-3 space-y-1">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-slate-500 dark:text-slate-400 text-sm">Equipment Name:</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ technicalData.patchposition.equipmentName }}</span>
|
||||
</div>
|
||||
<div v-if="technicalData.patchposition.equipmentPort" class="flex justify-between">
|
||||
<span class="text-slate-500 dark:text-slate-400 text-sm">Equipment Port:</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ technicalData.patchposition.equipmentPort }}</span>
|
||||
<!-- 1. Patchposition -->
|
||||
<div v-if="technicalData.patchposition?.equipmentName" class="bg-slate-50 dark:bg-slate-700/50 rounded-xl p-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-purple-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
<span class="text-xs font-semibold text-purple-600 dark:text-purple-400 uppercase tracking-wide">Patchposition</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-x-4 gap-y-1">
|
||||
<div class="text-xs"><span class="text-slate-400">Equipment:</span> <span class="font-mono font-semibold text-slate-800 dark:text-white">{{ technicalData.patchposition.equipmentName }}</span></div>
|
||||
<div v-if="technicalData.patchposition.equipmentPort" class="text-xs"><span class="text-slate-400">Port:</span> <span class="font-mono font-semibold text-slate-800 dark:text-white">{{ technicalData.patchposition.equipmentPort }}</span></div>
|
||||
</div>
|
||||
<div v-if="technicalData.patchposition.cluster || technicalData.patchposition.shelf || technicalData.patchposition.module" class="flex flex-wrap gap-x-4 gap-y-1 mt-2 pt-2 border-t border-slate-200 dark:border-slate-600">
|
||||
<div v-if="technicalData.patchposition.cluster" class="text-xs"><span class="text-slate-400">Cluster:</span> <span class="font-medium text-slate-700 dark:text-slate-300">{{ technicalData.patchposition.cluster }}</span></div>
|
||||
<div v-if="technicalData.patchposition.shelf" class="text-xs"><span class="text-slate-400">Shelf:</span> <span class="font-medium text-slate-700 dark:text-slate-300">{{ technicalData.patchposition.shelf }}</span></div>
|
||||
<div v-if="technicalData.patchposition.module" class="text-xs"><span class="text-slate-400">Module:</span> <span class="font-medium text-slate-700 dark:text-slate-300">{{ technicalData.patchposition.module }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Dropkabel -->
|
||||
<div v-if="technicalData.dropcable?.entries?.length" class="bg-slate-50 dark:bg-slate-700/50 rounded-xl p-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-sky-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
<span class="text-xs font-semibold text-sky-600 dark:text-sky-400 uppercase tracking-wide">Dropkabel</span>
|
||||
<span class="ml-auto text-[10px] bg-sky-100 dark:bg-sky-900/40 text-sky-600 dark:text-sky-400 px-1.5 py-0.5 rounded-full font-medium">{{ technicalData.dropcable.entries.length }}</span>
|
||||
</div>
|
||||
<div class="divide-y divide-slate-200 dark:divide-slate-600">
|
||||
<div v-for="(dk, idx) in technicalData.dropcable.entries" :key="idx" class="py-2 first:pt-0 last:pb-0">
|
||||
<div class="flex items-center justify-between gap-2 mb-1">
|
||||
<span class="font-mono text-xs font-semibold text-slate-800 dark:text-white">{{ dk.cable_id }}</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-medium"
|
||||
:class="dk.status === 'Planfreigabe' || dk.status === 'Plan released' ? 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400' : dk.status === 'Executed' || dk.status === 'Ausgeführt' ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-400' : 'bg-slate-200 text-slate-600 dark:bg-slate-600 dark:text-slate-300'">{{ dk.status || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-x-4 gap-y-1 text-xs">
|
||||
<div v-if="dk.type" class="text-slate-500 dark:text-slate-400 truncate max-w-[200px]" :title="dk.type">{{ dk.type }}</div>
|
||||
<div class="ml-auto flex gap-3">
|
||||
<span><span class="text-slate-400">Plan:</span> <span class="font-medium text-slate-700 dark:text-slate-300">{{ dk.laenge_plan || '-' }}</span></span>
|
||||
<span><span class="text-slate-400">Ist:</span> <span class="font-medium text-slate-700 dark:text-slate-300">{{ dk.laenge_ist || '-' }}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AHA Blätter -->
|
||||
<div v-if="technicalData.rimoWorkorders?.length" class="space-y-2">
|
||||
<div class="text-sm font-medium text-slate-500 dark:text-slate-400">AHA Blätter</div>
|
||||
<div v-for="wo in technicalData.rimoWorkorders" :key="wo.id"
|
||||
class="bg-slate-50 dark:bg-slate-700/50 rounded-lg p-3 flex items-center justify-between">
|
||||
<div>
|
||||
<div class="font-medium text-slate-900 dark:text-white">{{ wo.rimoName }}</div>
|
||||
<div class="text-xs text-slate-500 dark:text-slate-400">Status: {{ wo.rimoStatus }}</div>
|
||||
<!-- 3. Lageplan -->
|
||||
<div v-if="technicalData.dropcable?.map_file" class="bg-slate-50 dark:bg-slate-700/50 rounded-xl p-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-emerald-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"/>
|
||||
</svg>
|
||||
<span class="text-xs font-semibold text-emerald-600 dark:text-emerald-400 uppercase tracking-wide">Lageplan</span>
|
||||
</div>
|
||||
<button @click="openImageViewer(technicalData.dropcable.map_file.download_url)" class="w-full active:scale-[0.99] transition">
|
||||
<div class="bg-white dark:bg-slate-800 rounded-lg p-1 border border-slate-200 dark:border-slate-600">
|
||||
<img :src="technicalData.dropcable.map_file.download_url" class="w-full h-44 object-contain rounded" alt="Lageplan" @error="$event.target.closest('.bg-slate-50').style.display='none'">
|
||||
</div>
|
||||
<button @click="openPdfViewer(wo.downloadUrl, wo.rimoName)"
|
||||
class="flex items-center gap-2 px-3 py-2 bg-primary text-white rounded-lg text-sm font-medium active:scale-95 transition">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
|
||||
<div class="flex items-center justify-center gap-1 mt-2 text-[11px] text-slate-400 dark:text-slate-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7"/>
|
||||
</svg>
|
||||
AHA
|
||||
</button>
|
||||
Antippen zum Vergrößern
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 4. AHA Blatt -->
|
||||
<div v-if="technicalData.rimoWorkorders?.length" class="bg-slate-50 dark:bg-slate-700/50 rounded-xl p-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-amber-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
<span class="text-xs font-semibold text-amber-600 dark:text-amber-400 uppercase tracking-wide">AHA Blatt</span>
|
||||
</div>
|
||||
<div class="divide-y divide-slate-200 dark:divide-slate-600">
|
||||
<div v-for="wo in technicalData.rimoWorkorders" :key="wo.id" class="flex items-center justify-between gap-3 py-2 first:pt-0 last:pb-0">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="text-xs font-medium text-slate-800 dark:text-white truncate">{{ wo.rimoName }}</div>
|
||||
<div class="text-[11px] text-slate-500 dark:text-slate-400">{{ wo.rimoStatus }}</div>
|
||||
</div>
|
||||
<button @click="openPdfViewer(wo.downloadUrl, wo.rimoName)"
|
||||
class="flex-shrink-0 flex items-center gap-1 px-2.5 py-1.5 bg-amber-500 hover:bg-amber-600 text-white rounded-lg text-[11px] font-semibold active:scale-95 transition">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
PDF
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1483,6 +1556,37 @@ export default {
|
||||
</transition>
|
||||
</teleport>
|
||||
|
||||
<!-- Image Viewer Modal with Zoom -->
|
||||
<teleport to="body">
|
||||
<transition name="fade">
|
||||
<div v-if="showImageViewer" class="fixed inset-0 z-50 flex flex-col bg-black/95" @click.self="closeImageViewer">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between px-4 py-3 flex-shrink-0" style="padding-top: calc(0.75rem + env(safe-area-inset-top, 0px));">
|
||||
<h3 class="text-lg font-semibold text-white">Lageplan</h3>
|
||||
<button @click="closeImageViewer" class="p-2 -mr-2 text-white/70 hover:text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Image Content with pinch zoom -->
|
||||
<div class="flex-1 overflow-auto flex items-center justify-center p-4">
|
||||
<img
|
||||
:src="imageViewerUrl"
|
||||
class="max-w-none select-none"
|
||||
style="touch-action: pinch-zoom; max-height: calc(100vh - 150px); width: auto;"
|
||||
alt="Lageplan"
|
||||
@dblclick="$event.target.style.transform = $event.target.style.transform === 'scale(2)' ? 'scale(1)' : 'scale(2)'"
|
||||
>
|
||||
</div>
|
||||
<!-- Footer hint -->
|
||||
<div class="flex-shrink-0 px-4 py-3 text-center" style="padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));">
|
||||
<p class="text-white/50 text-xs">Pinch zum Zoomen • Doppeltippen für 2x</p>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</teleport>
|
||||
|
||||
<input
|
||||
ref="fileInputRef"
|
||||
type="file"
|
||||
|
||||
Reference in New Issue
Block a user