diff --git a/src/components/index.ts b/src/components/index.ts index 8ac94dd..62e7963 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -10,11 +10,11 @@ export { default as FileActionsMenu } from './FileActionsMenu.vue' // View components export * from './views' -// Dialog components -export * from './dialogs' - // Viewer export * from './viewer' +// Dialog components +export * from './dialogs' + // Editor export * from './editor' diff --git a/src/components/viewer/FilePreviewPopover.vue b/src/components/viewer/FilePreviewPopover.vue new file mode 100644 index 0000000..6068ba5 --- /dev/null +++ b/src/components/viewer/FilePreviewPopover.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/components/viewer/FileViewerDialog.vue b/src/components/viewer/FileViewerDialog.vue deleted file mode 100644 index a5d9f6e..0000000 --- a/src/components/viewer/FileViewerDialog.vue +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - - - - - - {{ filename }} - - - - {{ currentIndex + 1 }} / {{ allEntities.length }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - mdi-file-question-outline - No preview available - - {{ mime || 'Unknown file type' }} - - - Download file - - - - - - - - - - - - - - - - diff --git a/src/components/viewer/index.ts b/src/components/viewer/index.ts index a6f2e3b..93c5ea7 100644 --- a/src/components/viewer/index.ts +++ b/src/components/viewer/index.ts @@ -1 +1 @@ -export { default as FileViewerDialog } from './FileViewerDialog.vue' +export { default as FilePreviewPopover } from './FilePreviewPopover.vue' diff --git a/src/components/views/FilesDetailsView.vue b/src/components/views/FilesDetailsView.vue index 901f81a..d7b8309 100644 --- a/src/components/views/FilesDetailsView.vue +++ b/src/components/views/FilesDetailsView.vue @@ -3,17 +3,20 @@ import { computed } from 'vue' import { CollectionObject } from '@DocumentsManager/models/collection' import { EntityObject } from '@DocumentsManager/models/entity' import { getFileIcon, formatSize, formatDate } from '@/utils/fileHelpers' -import { FileActionsMenu } from '@/components' +import { FileActionsMenu, FilePreviewPopover } from '@/components' type ItemWithType = { item: CollectionObject | EntityObject type: 'collection' | 'entity' } +type PreviewSource = (item: { id: string; meta?: Record }) => string | Blob | Promise + const props = defineProps<{ collections: CollectionObject[] entities: EntityObject[] selectedIds: Set + previewSource?: PreviewSource }>() const emit = defineEmits<{ @@ -105,6 +108,13 @@ function isCollection(wrapped: ItemWithType): wrapped is { item: CollectionObjec @show-details="emit('show-details', $event)" /> + + diff --git a/src/components/views/FilesGridView.vue b/src/components/views/FilesGridView.vue index b90c5ff..921aef2 100644 --- a/src/components/views/FilesGridView.vue +++ b/src/components/views/FilesGridView.vue @@ -2,12 +2,15 @@ import { CollectionObject } from '@DocumentsManager/models/collection' import { EntityObject } from '@DocumentsManager/models/entity' import { getFileIcon, formatSize } from '@/utils/fileHelpers' -import { FileActionsMenu } from '@/components' +import { FileActionsMenu, FilePreviewPopover } from '@/components' + +type PreviewSource = (item: { id: string; meta?: Record }) => string | Blob | Promise defineProps<{ collections: CollectionObject[] entities: EntityObject[] selectedIds: Set + previewSource?: PreviewSource }>() const emit = defineEmits<{ @@ -73,6 +76,13 @@ const emit = defineEmits<{ {{ getFileIcon(entity) }} {{ entity.properties.label || String(entity.identifier ?? '') }} {{ formatSize(entity.properties.size) }} + + diff --git a/src/components/views/FilesListView.vue b/src/components/views/FilesListView.vue index 5332507..dcf3354 100644 --- a/src/components/views/FilesListView.vue +++ b/src/components/views/FilesListView.vue @@ -3,17 +3,20 @@ import { computed } from 'vue' import { CollectionObject } from '@DocumentsManager/models/collection' import { EntityObject } from '@DocumentsManager/models/entity' import { getFileIcon, formatSize } from '@/utils/fileHelpers' -import { FileActionsMenu } from '@/components' +import { FileActionsMenu, FilePreviewPopover } from '@/components' type ItemWithType = { item: CollectionObject | EntityObject type: 'collection' | 'entity' } +type PreviewSource = (item: { id: string; meta?: Record }) => string | Blob | Promise + const props = defineProps<{ collections: CollectionObject[] entities: EntityObject[] selectedIds: Set + previewSource?: PreviewSource }>() const emit = defineEmits<{ @@ -90,6 +93,13 @@ function isCollection(wrapped: ItemWithType): wrapped is { item: CollectionObjec @show-details="emit('show-details', $event)" /> + + diff --git a/src/composables/index.ts b/src/composables/index.ts index 83f586b..9992cfa 100644 --- a/src/composables/index.ts +++ b/src/composables/index.ts @@ -5,11 +5,9 @@ export { useFileManager } from './useFileManager' export { useFileSelection } from './useFileSelection' export { useFileUpload } from './useFileUpload' -export { useFileViewer } from './useFileViewer' export { useFileEditor } from './useFileEditor' export type { UseFileManagerOptions } from './useFileManager' export type { UseFileSelectionOptions } from './useFileSelection' export type { UseFileUploadOptions, FileUploadProgress } from './useFileUpload' -export type { UseFileViewerReturn } from './useFileViewer' export type { UseFileEditorReturn } from './useFileEditor' diff --git a/src/composables/useFileManager.ts b/src/composables/useFileManager.ts index bb9daa8..2a1cbda 100644 --- a/src/composables/useFileManager.ts +++ b/src/composables/useFileManager.ts @@ -241,8 +241,8 @@ export function useFileManager(options: UseFileManagerOptions) { // Initialize - fetch providers, services, and initial nodes if autoFetch const initialize = async () => { - await providersStore.list() - await servicesStore.list({ [currentProviderId()]: true }) + await providersStore.list([currentProviderId()]) + await servicesStore.list() if (autoFetch) { await refresh() } diff --git a/src/composables/useFileViewer.ts b/src/composables/useFileViewer.ts deleted file mode 100644 index 12c3f17..0000000 --- a/src/composables/useFileViewer.ts +++ /dev/null @@ -1,81 +0,0 @@ -/** - * useFileViewer — resolves which registered viewer can handle a given MIME type. - * - * Other modules register viewers at the `documents_file_viewer` integration - * point by including an entry in their `integrations.ts`: - * - * ```ts - * documents_file_viewer: [{ - * id: 'my_viewer', - * meta: { mimeTypes: ['application/pdf'] }, - * component: () => import('./components/MyViewer.vue'), - * }] - * ``` - * - * Viewer components receive the props: `url: string`, `entity: EntityObject`, `mime: string`. - */ - -import { useIntegrationStore } from '@KTXC' -import type { EntityObject } from '@DocumentsManager/models/entity' - -const INTEGRATION_POINT = 'documents_file_viewer' - -function mimeMatchesPattern(mime: string, pattern: string): boolean { - if (pattern.endsWith('/*')) { - // e.g. 'image/*' matches 'image/png', 'image/jpeg', … - return mime.startsWith(pattern.slice(0, -1)) - } - return mime === pattern -} - -function viewerMatchesMime( - mime: string, - mimeTypes?: string[], - mimePatterns?: string[], -): boolean { - if (mimeTypes?.includes(mime)) return true - if (mimePatterns) { - for (const pattern of mimePatterns) { - if (mimeMatchesPattern(mime, pattern)) return true - } - } - return false -} - -export function useFileViewer() { - const integrationStore = useIntegrationStore() - - /** - * Returns the highest-priority registered viewer that can handle `mime`, - * or `null` if none is found. - */ - function findViewer(mime: string) { - // getItems() already returns items sorted by priority (ascending) - const viewers = integrationStore.getItems(INTEGRATION_POINT) - for (const viewer of viewers) { - if ( - viewerMatchesMime( - mime, - viewer.meta?.mimeTypes as string[] | undefined, - viewer.meta?.mimePatterns as string[] | undefined, - ) - ) { - return viewer - } - } - return null - } - - /** - * Convenience: returns true if any registered viewer can open this entity. - */ - function canOpen(entity: EntityObject): boolean { - const mime = entity.properties.mime - if (!mime) return false - return findViewer(mime) !== null - } - - return { findViewer, canOpen } -} - -export type UseFileViewerReturn = ReturnType diff --git a/src/pages/FilesPage.vue b/src/pages/FilesPage.vue index 005e3b3..ada8258 100644 --- a/src/pages/FilesPage.vue +++ b/src/pages/FilesPage.vue @@ -1,7 +1,7 @@
No preview available
- {{ mime || 'Unknown file type' }} -