feat: add document preview overlay

This commit is contained in:
Matthieu
2025-09-17 17:12:41 +02:00
parent 8a32ef4bbc
commit 37c66ac3d6
8 changed files with 617 additions and 1 deletions

View File

@@ -11,6 +11,12 @@
</div>
</div>
<DocumentPreviewModal
:document="previewDocument"
:visible="previewVisible"
@close="closePreview"
/>
<section class="card bg-base-100 shadow-lg">
<div class="card-body space-y-6">
<div class="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
@@ -94,7 +100,16 @@
<td>{{ formatDate(document.createdAt) }}</td>
<td class="text-right">
<div class="flex justify-end gap-2">
<button class="btn btn-ghost btn-xs" @click="downloadDocument(document)">
<button
class="btn btn-ghost btn-xs"
type="button"
:disabled="!canPreviewDocument(document)"
:title="canPreviewDocument(document) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
@click="openPreview(document)"
>
Consulter
</button>
<button class="btn btn-ghost btn-xs" type="button" @click="downloadDocument(document)">
Télécharger
</button>
</div>
@@ -112,11 +127,15 @@
import { ref, computed, onMounted } from 'vue'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
import { canPreviewDocument } from '~/utils/documentPreview'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
const { documents, loading, loadDocuments } = useDocuments()
const searchTerm = ref('')
const attachmentFilter = ref('all')
const previewDocument = ref(null)
const previewVisible = ref(false)
onMounted(() => {
loadDocuments()
@@ -187,4 +206,15 @@ const downloadDocument = (doc) => {
window.open(doc.path, '_blank')
}
const openPreview = (doc) => {
if (!canPreviewDocument(doc)) return
previewDocument.value = doc
previewVisible.value = true
}
const closePreview = () => {
previewVisible.value = false
previewDocument.value = null
}
</script>

View File

@@ -7,6 +7,12 @@
<!-- Machine Details -->
<div v-else-if="machine" class="space-y-8">
<DocumentPreviewModal
:document="previewDocument"
:visible="previewVisible"
@close="closePreview"
/>
<!-- Header with Edit Button -->
<div class="flex justify-between items-center">
<h1 class="text-3xl font-bold">Détails de la machine</h1>
@@ -259,6 +265,15 @@
</div>
</div>
<div class="flex items-center gap-2">
<button
type="button"
class="btn btn-ghost btn-xs"
:disabled="!canPreviewDocument(document)"
:title="canPreviewDocument(document) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
@click="openPreview(document)"
>
Consulter
</button>
<button type="button" class="btn btn-ghost btn-xs" @click="downloadDocument(document)">
Télécharger
</button>
@@ -365,10 +380,12 @@ import { useApi } from '~/composables/useApi'
import { useToast } from '~/composables/useToast'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
import { canPreviewDocument } from '~/utils/documentPreview'
import ComponentHierarchy from '~/components/ComponentHierarchy.vue'
import DocumentUpload from '~/components/DocumentUpload.vue'
import ConstructeurSelect from '~/components/ConstructeurSelect.vue'
import { useConstructeurs } from '~/composables/useConstructeurs'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
const route = useRoute()
const machineId = route.params.id
@@ -423,6 +440,8 @@ const machineCustomFieldValues = reactive({})
const machineDocumentFiles = ref([])
const machineDocumentsUploading = ref(false)
const machineDocumentsLoaded = ref(false)
const previewDocument = ref(null)
const previewVisible = ref(false)
const handleMachineConstructeurChange = async (value) => {
machineConstructeurId.value = value
@@ -537,6 +556,17 @@ const downloadDocument = (doc) => {
window.open(doc.path, '_blank')
}
const openPreview = (doc) => {
if (!canPreviewDocument(doc)) return
previewDocument.value = doc
previewVisible.value = true
}
const closePreview = () => {
previewVisible.value = false
previewDocument.value = null
}
const formatSize = (size) => {
if (size === undefined || size === null) return '—'
if (size === 0) return '0 B'

View File

@@ -1,5 +1,10 @@
<template>
<main class="container mx-auto px-6 py-8">
<DocumentPreviewModal
:document="previewDocument"
:visible="previewVisible"
@close="closePreview"
/>
<!-- Hero Section -->
<div class="hero min-h-[30vh] bg-gradient-to-r from-primary to-secondary">
<div class="hero-content text-center text-neutral-content">
@@ -328,6 +333,15 @@
</div>
</div>
<div class="flex items-center gap-2">
<button
type="button"
class="btn btn-ghost btn-xs"
:disabled="!canPreviewDocument(document)"
:title="canPreviewDocument(document) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
@click="openPreview(document)"
>
Consulter
</button>
<button type="button" class="btn btn-ghost btn-xs" @click="downloadDocument(document)">
Télécharger
</button>
@@ -365,7 +379,9 @@ import { useSites } from '~/composables/useSites'
import { useToast } from '~/composables/useToast'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
import { canPreviewDocument } from '~/utils/documentPreview'
import DocumentUpload from '~/components/DocumentUpload.vue'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
const { sites, loading, loadSites, createSite, updateSite, deleteSite } = useSites()
const { uploadDocuments, deleteDocument, loadDocumentsBySite } = useDocuments()
@@ -396,6 +412,8 @@ const editSiteForm = reactive({
const selectedFiles = ref([])
const uploadingDocuments = ref(false)
const previewDocument = ref(null)
const previewVisible = ref(false)
const siteDocuments = computed(() => siteBeingEdited.value?.documents || [])
const documentIcon = (doc) => getFileIcon({ name: doc.filename || doc.name, mime: doc.mimeType })
@@ -543,6 +561,17 @@ const downloadDocument = (doc) => {
window.open(doc.path, '_blank')
}
const openPreview = (doc) => {
if (!canPreviewDocument(doc)) return
previewDocument.value = doc
previewVisible.value = true
}
const closePreview = () => {
previewVisible.value = false
previewDocument.value = null
}
const refreshSiteDocuments = async (siteId) => {
if (!siteId) return
const result = await loadDocumentsBySite(siteId, { updateStore: false })