Add file attachment support to email composer

- Add file browser integration for selecting attachments
- Display attached files with remove functionality in composer
- Include attachments in email sending process
- Show attachment info in email thread display
- Update server endpoints to handle file attachments
- Minor UI improvements to EOI status badge layout
This commit is contained in:
2025-06-10 02:39:00 +02:00
parent bb2f5d37c8
commit b332f913a6
5 changed files with 134 additions and 51 deletions

View File

@@ -20,16 +20,15 @@
</div>
<!-- EOI Status Badge -->
<div v-if="hasEOI" class="mb-4">
<div v-if="hasEOI" class="mb-4 d-flex align-center">
<v-chip
:color="getStatusColor(interest['EOI Status'])"
variant="tonal"
prepend-icon="mdi-file-document-check"
class="mr-2"
>
{{ interest['EOI Status'] }}
</v-chip>
<span v-if="interest['EOI Time Sent']" class="text-caption text-grey-darken-1">
<span v-if="interest['EOI Time Sent']" class="text-caption text-grey-darken-1 ml-3">
Sent: {{ formatDate(interest['EOI Time Sent']) }}
</span>
</div>

View File

@@ -35,6 +35,21 @@
placeholder="Type your message here..."
/>
<!-- File Attachments -->
<div v-if="attachments.length > 0" class="mb-4">
<div class="text-subtitle-2 mb-2">Attachments:</div>
<v-chip
v-for="(file, index) in attachments"
:key="index"
closable
@click:close="removeAttachment(index)"
class="mr-2 mb-2"
>
<v-icon start>mdi-paperclip</v-icon>
{{ file.name }}
</v-chip>
</div>
<!-- Quick Actions -->
<div class="d-flex ga-2 mb-4">
<v-btn
@@ -57,6 +72,15 @@
<v-icon start>mdi-form-select</v-icon>
Insert Form Link
</v-btn>
<v-btn
variant="outlined"
size="small"
@click="showFileBrowser = true"
:disabled="sending"
>
<v-icon start>mdi-paperclip</v-icon>
Attach File
</v-btn>
<v-spacer />
<v-btn
variant="text"
@@ -145,11 +169,42 @@
</v-form>
</v-card-text>
</v-card>
<!-- File Browser Dialog -->
<v-dialog v-model="showFileBrowser" max-width="800">
<v-card>
<v-card-title>
Select Files to Attach
<v-spacer />
<v-btn icon @click="showFileBrowser = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text style="height: 500px; overflow-y: auto;">
<file-browser-component
v-if="showFileBrowser"
:selection-mode="true"
@file-selected="onFileSelected"
/>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="showFileBrowser = false">Cancel</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue';
import type { Interest } from '@/utils/types';
import FileBrowserComponent from '~/pages/dashboard/file-browser.vue';
interface AttachedFile {
name: string;
path: string;
size: number;
}
interface Props {
interest: Interest;
@@ -171,6 +226,8 @@ const sending = ref(false);
const generatingEOI = ref(false);
const showSignatureSettings = ref(false);
const includeSignature = ref(true);
const showFileBrowser = ref(false);
const attachments = ref<AttachedFile[]>([]);
const email = ref({
to: '',
@@ -269,6 +326,29 @@ const getSignaturePreview = () => {
</div>`;
};
const onFileSelected = (file: any) => {
// Add the selected file to attachments
const attachment: AttachedFile = {
name: file.name,
path: file.path || file.name,
size: file.size || 0
};
// Check if file is already attached
if (!attachments.value.some(a => a.path === attachment.path)) {
attachments.value.push(attachment);
toast.success(`${file.name} attached`);
} else {
toast.info(`${file.name} is already attached`);
}
showFileBrowser.value = false;
};
const removeAttachment = (index: number) => {
attachments.value.splice(index, 1);
};
const sendEmail = async () => {
const { valid } = await form.value.validate();
if (!valid) return;
@@ -288,7 +368,8 @@ const sendEmail = async () => {
interestId: props.interest.Id,
sessionId: getSessionId(),
includeSignature: includeSignature.value,
signatureConfig: includeSignature.value ? signatureConfig.value : undefined
signatureConfig: includeSignature.value ? signatureConfig.value : undefined,
attachments: attachments.value
}
});
@@ -297,6 +378,7 @@ const sendEmail = async () => {
// Clear form
email.value.subject = '';
email.value.body = '';
attachments.value = [];
emit('sent', response.messageId);
}
} catch (error: any) {

View File

@@ -44,20 +44,7 @@
<v-icon start>mdi-email-outline</v-icon>
Request Info
</v-btn>
<v-btn
@click="eoiSendToSales"
variant="text"
:loading="isSendingEOI"
:disabled="
isRequestingMoreInfo ||
isRequestingMoreInformation ||
isSendingEOI ||
isDeleting
"
>
<v-icon start>mdi-send</v-icon>
EOI to Sales
</v-btn>
<!-- EOI to Sales button hidden -->
<v-btn
@click="confirmDelete"
variant="flat"
@@ -206,26 +193,7 @@
<span class="text-caption">Request Info</span>
</v-btn>
</v-col>
<v-col cols="6">
<v-btn
@click="eoiSendToSales"
variant="outlined"
color="primary"
block
:loading="isSendingEOI"
:disabled="
isRequestingMoreInfo ||
isRequestingMoreInformation ||
isSendingEOI
"
class="mb-2 d-flex flex-column"
size="large"
>
<v-icon size="large" class="mb-1">mdi-send</v-icon>
<span class="text-caption">EOI to Sales</span>
</v-btn>
</v-col>
<v-col cols="6">
<v-col cols="12">
<v-btn
@click="saveInterest"
variant="flat"