From 0a541f658d7756dc7f802284798ce727da72047e Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Jun 2025 18:04:31 +0200 Subject: [PATCH] Improve email loading performance and fix UI issues - Fixed refresh button icon not displaying (changed from icon prop to v-icon element) - Reduced default email limit from 50 to 20 to improve loading speed - Optimized cached email loading to only load most recent emails (up to limit) - Fixed CommonJS require error in email-utils.ts (changed to ES module import) - Added sorting to cached files to ensure newest emails are loaded first This should significantly improve email loading performance from 578 cached files down to max 20 --- components/ClientEmailSection.vue | 4 +- server/api/email/fetch-thread.ts | 68 ++++++++++++++++--------------- server/utils/email-utils.ts | 2 +- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/components/ClientEmailSection.vue b/components/ClientEmailSection.vue index 3924c44..e635f02 100644 --- a/components/ClientEmailSection.vue +++ b/components/ClientEmailSection.vue @@ -29,12 +29,12 @@ - Refresh Emails + mdi-refresh + Refresh Emails diff --git a/server/api/email/fetch-thread.ts b/server/api/email/fetch-thread.ts index f41d816..7f80edc 100644 --- a/server/api/email/fetch-thread.ts +++ b/server/api/email/fetch-thread.ts @@ -24,8 +24,8 @@ export default defineEventHandler(async (event) => { try { const body = await readBody(event); - // Increase limit to get more complete threads - const { clientEmail, interestId, sessionId, limit = 50 } = body; + // Limit emails to improve performance + const { clientEmail, interestId, sessionId, limit = 20 } = body; if (!clientEmail || !sessionId) { throw createError({ @@ -84,36 +84,40 @@ export default defineEventHandler(async (event) => { console.log('Found cached email files:', files.length); - for (const file of files) { - if (file.name.endsWith('.json') && !file.isFolder) { - try { - // Read file directly on server using MinIO client (works with private buckets) - const client = getMinioClient(); - // Use the client-emails bucket directly - const bucketName = 'client-emails'; - - // The file.name is already the correct path within the bucket - const fileName = file.name; - - // Get object as stream - const stream = await client.getObject(bucketName, fileName); - - // Convert stream to string - let data = ''; - stream.on('data', (chunk) => { - data += chunk; - }); - - await new Promise((resolve, reject) => { - stream.on('end', () => resolve(data)); - stream.on('error', reject); - }); - - const emailData = JSON.parse(data); - cachedEmails.push(emailData); - } catch (err) { - console.error('Failed to read cached email:', file.name, err); - } + // Limit cached emails to most recent ones + const sortedFiles = files + .filter(f => f.name.endsWith('.json')) + .sort((a, b) => b.name.localeCompare(a.name)) // Sort by filename (newer files have higher timestamps) + .slice(0, limit); // Only load up to the limit + + for (const file of sortedFiles) { + try { + // Read file directly on server using MinIO client (works with private buckets) + const client = getMinioClient(); + // Use the client-emails bucket directly + const bucketName = 'client-emails'; + + // The file.name is already the correct path within the bucket + const fileName = file.name; + + // Get object as stream + const stream = await client.getObject(bucketName, fileName); + + // Convert stream to string + let data = ''; + stream.on('data', (chunk) => { + data += chunk; + }); + + await new Promise((resolve, reject) => { + stream.on('end', () => resolve(data)); + stream.on('error', reject); + }); + + const emailData = JSON.parse(data); + cachedEmails.push(emailData); + } catch (err) { + console.error('Failed to read cached email:', file.name, err); } } } catch (err) { diff --git a/server/utils/email-utils.ts b/server/utils/email-utils.ts index 27d3c46..13d23b8 100644 --- a/server/utils/email-utils.ts +++ b/server/utils/email-utils.ts @@ -1,6 +1,6 @@ import { simpleParser } from 'mailparser'; import type { ParsedMail } from 'mailparser'; -const Imap = require('imap'); +import Imap from 'imap'; export type { ParsedMail };