Files
FEDEO/frontend/components/EntityShowSubFiles.vue
2026-01-06 12:09:31 +01:00

135 lines
3.6 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
const props = defineProps({
item: { type: Object, required: true },
type: { type: String, required: true },
topLevelType: { type: String, required: true },
platform: { type: String, required: true }
})
const emit = defineEmits(["updateNeeded"])
const files = useFiles()
const availableFiles = ref([])
const activeFile = ref(null)
const showViewer = ref(false)
const setup = async () => {
if (props.item.files?.length > 0) {
availableFiles.value =
(await files.selectSomeDocuments(props.item.files.map((f) => f.id))) || []
}
}
setup()
// Datei öffnen (Mobile/Tablet)
function openFile(file) {
activeFile.value = file
showViewer.value = true
}
function closeViewer() {
showViewer.value = false
activeFile.value = null
}
// PDF oder Bild?
function isPdf(file) {
return file.path.includes("pdf")
}
function isImage(file) {
return file.mimetype?.startsWith("image/")
}
</script>
<template>
<UCard class="mt-5" :style="props.platform !== 'mobile' ? 'height: 80vh' : ''">
<template #header>
<span>Dateien</span>
</template>
<!-- Upload -->
<Toolbar>
<DocumentUpload
:type="props.topLevelType.substring(0, props.topLevelType.length - 1)"
:element-id="props.item.id"
@uploadFinished="emit('updateNeeded')"
/>
</Toolbar>
<!-- 📱 MOBILE: File Cards -->
<div v-if="props.platform === 'mobile'" class="space-y-3 mt-3">
<div
v-for="file in availableFiles"
:key="file.id"
class="p-4 border rounded-xl bg-gray-50 dark:bg-gray-900 flex items-center justify-between active:scale-95 transition cursor-pointer"
@click="openFile(file)"
>
<div>
<p class="font-semibold truncate max-w-[200px]">{{ file?.path?.split("/").pop() }}</p>
</div>
<UIcon
name="i-heroicons-chevron-right-20-solid"
class="w-5 h-5 text-gray-400"
/>
</div>
<UAlert
v-if="!availableFiles.length"
icon="i-heroicons-x-mark"
title="Keine Dateien verfügbar"
/>
</div>
<!-- 🖥 DESKTOP: Classic List -->
<template v-else>
<DocumentList
:key="props.item.files.length"
:documents="availableFiles"
v-if="availableFiles.length > 0"
/>
<UAlert v-else icon="i-heroicons-x-mark" title="Keine Dateien verfügbar" />
</template>
</UCard>
<!-- 📱 PDF / IMG Viewer Slideover -->
<UModal v-model="showViewer" side="bottom" class="h-[100dvh]" fullscreen>
<!-- Header -->
<div class="p-4 border-b flex justify-between items-center flex-shrink-0">
<h3 class="font-bold truncate max-w-[70vw]">{{ activeFile?.path?.split("/").pop() }}</h3>
<UButton icon="i-heroicons-x-mark" variant="ghost" @click="closeViewer" />
</div>
<!-- Content -->
<div class="flex-1 overflow-y-auto m-2">
<!-- PDF -->
<div v-if="activeFile && isPdf(activeFile)" class="h-full">
<PDFViewer
:no-controls="true"
:file-id="activeFile.id"
location="fileviewer-mobile"
class="h-full"
/>
</div>
<!-- IMAGE -->
<div
v-else-if="activeFile && isImage(activeFile)"
class="p-4 flex justify-center"
>
<img
:src="activeFile.url"
class="max-w-full max-h-[80vh] rounded-lg shadow"
/>
</div>
<UAlert
v-else
title="Nicht unterstützter Dateityp"
icon="i-heroicons-exclamation-triangle"
/>
</div>
</UModal>
</template>