feat: add attach from documents

Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
2026-08-15 12:55:59 -04:00
parent 8a18494883
commit 4839f822fa
9 changed files with 591 additions and 107 deletions
+30 -3
View File
@@ -12,6 +12,7 @@ import type { CollectionObject, MessageAddressObject } from '@MailManager/models
import { useMailOperationsStore } from '@/stores/mailOperationsStore'
import { useMailCompositionStore } from '@/stores/mailCompositionStore'
import { ComposerMode } from '@/types/composer'
import { documentsSelectorComponent } from '@/services/documentsSelector'
import ComposerToolbar from '@/components/composer/ComposerToolbar.vue'
import ComposerSender from '@/components/composer/ComposerSender.vue'
import ComposerRecipients from '@/components/composer/ComposerRecipients.vue'
@@ -48,6 +49,8 @@ const {
const showCc = ref(false)
const showBcc = ref(false)
const applyingDraftToEditor = ref(false)
const showDocumentSelector = ref(false)
const documentSelector = computed(() => documentsSelectorComponent())
const sender = computed({
get: () => activeDraft.value?.sender ?? null,
@@ -166,8 +169,23 @@ const handleSend = async () => {
await compositionStore.sendDraft()
}
const handleAttach = async (files: File[]) => {
await compositionStore.addAttachments(files)
const handleAttachFromDevice = async (files: File[]) => {
await compositionStore.addAttachmentsFromDevice(files)
}
const handleAttachFromDocuments = () => {
showDocumentSelector.value = true
}
const handleDocumentsSelected = async (items: { kind: 'entity' | 'collection'; identifier: string; name: string; mimeType?: string; size?: number }[]) => {
// The dialog defaults to entities-only (no `selectable` prop passed below), but
// filter defensively since mail can't attach a folder as a single file blob.
const files = items.filter(item => item.kind === 'entity')
if (files.length === 0) {
return
}
await compositionStore.addAttachmentsFromDocuments(files)
showDocumentSelector.value = false
}
const handleDetach = async (identifier: string) => {
@@ -264,9 +282,18 @@ const isActive = (name: string, attrs?: any) => {
@bullet-list="toggleBulletList"
@ordered-list="toggleOrderedList"
@link="toggleLink"
@attach="handleAttach"
@attach-from-device="handleAttachFromDevice"
@attach-from-documents="handleAttachFromDocuments"
/>
</div>
<component
:is="documentSelector"
v-if="documentSelector"
v-model="showDocumentSelector"
:selectable="['entity']"
@select="handleDocumentsSelected"
/>
</div>
</template>
+9 -2
View File
@@ -2,6 +2,7 @@
import { ref } from 'vue'
import type { PropType } from 'vue'
import { EditorContent, type Editor } from '@tiptap/vue-3'
import { documentsSelectorAvailable } from '@/services/documentsSelector'
defineProps({
editor: {
@@ -41,7 +42,8 @@ const emit = defineEmits<{
bulletList: []
orderedList: []
link: []
attach: [files: File[]]
attachFromDevice: [files: File[]]
attachFromDocuments: []
}>()
const fileInput = ref<HTMLInputElement | null>(null)
@@ -54,7 +56,7 @@ function handleFileChange(event: Event) {
const input = event.target as HTMLInputElement | null
const files = input?.files ? Array.from(input.files) : []
if (files.length > 0) {
emit('attach', files)
emit('attachFromDevice', files)
}
if (input) {
input.value = ''
@@ -142,6 +144,11 @@ function handleFileChange(event: Event) {
<v-icon>mdi-paperclip</v-icon>
<v-tooltip activator="parent" location="bottom">Attach Files</v-tooltip>
</v-btn>
<v-btn v-if="documentsSelectorAvailable()" icon size="small" @click="$emit('attachFromDocuments')">
<v-icon>mdi-folder-search-outline</v-icon>
<v-tooltip activator="parent" location="bottom">Attach from Documents</v-tooltip>
</v-btn>
</v-toolbar>
<v-divider />