import { DeesElement, customElement, html, css, cssManager, state, type TemplateResult, } from '@design.estate/dees-element'; import type { DeesAppui } from '@design.estate/dees-catalog'; import type { IEmail, TEmailDirection } from './sz-mta-list-view.js'; import type { IEmailDetail } from './sz-mta-detail-view.js'; import './index.js'; declare global { interface HTMLElementTagNameMap { 'sz-demo-view-mta': SzDemoViewMta; } } @customElement('sz-demo-view-mta') export class SzDemoViewMta extends DeesElement { private appui: DeesAppui | null = null; @state() private accessor currentView: 'list' | 'detail' = 'list'; @state() private accessor selectedEmail: IEmailDetail | null = null; @state() private accessor currentDirectionFilter: TEmailDirection | 'all' = 'all'; private demoEmails: IEmail[] = [ { id: '1', direction: 'outbound', status: 'delivered', from: 'noreply@serve.zone', to: 'user@example.com', subject: 'Welcome to serve.zone', timestamp: '2024-01-15 14:30:22', messageId: '', size: '12.4 KB' }, { id: '2', direction: 'outbound', status: 'bounced', from: 'alerts@serve.zone', to: 'invalid@nowhere.test', subject: 'Service Alert: CPU Usage High', timestamp: '2024-01-15 14:28:10', messageId: '', size: '8.2 KB' }, { id: '3', direction: 'inbound', status: 'delivered', from: 'support@customer.com', to: 'admin@serve.zone', subject: 'Re: Infrastructure Review', timestamp: '2024-01-15 14:25:00', messageId: '', size: '24.1 KB' }, { id: '4', direction: 'outbound', status: 'rejected', from: 'billing@serve.zone', to: 'blocked@spam-domain.test', subject: 'Invoice #2024-001', timestamp: '2024-01-15 14:20:45', messageId: '', size: '45.6 KB' }, { id: '5', direction: 'outbound', status: 'deferred', from: 'noreply@serve.zone', to: 'slow@remote-server.test', subject: 'Password Reset Request', timestamp: '2024-01-15 14:15:30', messageId: '', size: '6.8 KB' }, { id: '6', direction: 'inbound', status: 'delivered', from: 'ci@github.com', to: 'devops@serve.zone', subject: 'Build #4521 passed', timestamp: '2024-01-15 14:10:00', messageId: '', size: '15.3 KB' }, { id: '7', direction: 'outbound', status: 'pending', from: 'reports@serve.zone', to: 'team@serve.zone', subject: 'Weekly Infrastructure Report', timestamp: '2024-01-15 14:05:00', messageId: '', size: '102.7 KB' }, { id: '8', direction: 'inbound', status: 'delivered', from: 'monitoring@uptime.io', to: 'ops@serve.zone', subject: 'Uptime Report: 99.98%', timestamp: '2024-01-15 13:55:00', messageId: '', size: '9.1 KB' }, ]; private demoEmailDetails: Record = { '1': { id: '1', direction: 'outbound', status: 'delivered', from: 'noreply@serve.zone', to: 'user@example.com', toList: ['user@example.com'], subject: 'Welcome to serve.zone', timestamp: '2024-01-15 14:30:22', messageId: '', size: '12.4 KB', smtpLog: [ { timestamp: '14:30:20', direction: 'client', command: 'EHLO mail.serve.zone' }, { timestamp: '14:30:20', direction: 'server', command: '250-mail.example.com Hello', responseCode: 250 }, { timestamp: '14:30:20', direction: 'server', command: '250-STARTTLS', responseCode: 250 }, { timestamp: '14:30:20', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 }, { timestamp: '14:30:20', direction: 'client', command: 'STARTTLS' }, { timestamp: '14:30:21', direction: 'server', command: '220 Ready to start TLS', responseCode: 220 }, { timestamp: '14:30:21', direction: 'client', command: 'EHLO mail.serve.zone' }, { timestamp: '14:30:21', direction: 'server', command: '250-mail.example.com Hello', responseCode: 250 }, { timestamp: '14:30:21', direction: 'server', command: '250-AUTH PLAIN LOGIN', responseCode: 250 }, { timestamp: '14:30:21', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 }, { timestamp: '14:30:21', direction: 'client', command: 'AUTH PLAIN AHVzZXIAcGFzc3dvcmQ=' }, { timestamp: '14:30:21', direction: 'server', command: '235 2.7.0 Authentication successful', responseCode: 235 }, { timestamp: '14:30:21', direction: 'client', command: 'MAIL FROM:' }, { timestamp: '14:30:21', direction: 'server', command: '250 OK', responseCode: 250 }, { timestamp: '14:30:21', direction: 'client', command: 'RCPT TO:' }, { timestamp: '14:30:21', direction: 'server', command: '250 Accepted', responseCode: 250 }, { timestamp: '14:30:22', direction: 'client', command: 'DATA' }, { timestamp: '14:30:22', direction: 'server', command: '354 Enter message, ending with "." on a line by itself', responseCode: 354 }, { timestamp: '14:30:22', direction: 'client', command: '.' }, { timestamp: '14:30:22', direction: 'server', command: '250 OK id=1pQ2rS-0003Ab-C4', responseCode: 250 }, { timestamp: '14:30:22', direction: 'client', command: 'QUIT' }, { timestamp: '14:30:22', direction: 'server', command: '221 mail.example.com closing connection', responseCode: 221 }, ], connectionInfo: { sourceIp: '10.0.1.50', sourceHostname: 'mail.serve.zone', destinationIp: '93.184.216.34', destinationPort: 25, tlsVersion: 'TLSv1.3', tlsCipher: 'TLS_AES_256_GCM_SHA384', authenticated: true, authMethod: 'PLAIN', authUser: 'noreply@serve.zone', }, authenticationResults: { spf: 'pass', spfDomain: 'serve.zone', dkim: 'pass', dkimDomain: 'serve.zone', dmarc: 'pass', dmarcPolicy: 'reject', }, headers: { 'From': 'noreply@serve.zone', 'To': 'user@example.com', 'Subject': 'Welcome to serve.zone', 'Date': 'Mon, 15 Jan 2024 14:30:22 +0000', 'MIME-Version': '1.0', 'Content-Type': 'text/html; charset=UTF-8', }, body: '\nWelcome\n\n

Welcome to serve.zone!

\n

Your account has been created successfully.

\n

Get started by visiting your dashboard.

\n\n', }, '2': { id: '2', direction: 'outbound', status: 'bounced', from: 'alerts@serve.zone', to: 'invalid@nowhere.test', toList: ['invalid@nowhere.test'], subject: 'Service Alert: CPU Usage High', timestamp: '2024-01-15 14:28:10', messageId: '', size: '8.2 KB', rejectionReason: '550 5.1.1 The email account that you tried to reach does not exist.', bounceMessage: 'Delivery to the following recipient failed permanently:\n\n invalid@nowhere.test\n\nTechnical details of permanent failure:\nGoogle tried to deliver your message, but it was rejected by the server for the recipient domain nowhere.test.', smtpLog: [ { timestamp: '14:28:08', direction: 'client', command: 'EHLO mail.serve.zone' }, { timestamp: '14:28:08', direction: 'server', command: '250-mail.nowhere.test Hello', responseCode: 250 }, { timestamp: '14:28:08', direction: 'client', command: 'MAIL FROM:' }, { timestamp: '14:28:09', direction: 'server', command: '250 OK', responseCode: 250 }, { timestamp: '14:28:09', direction: 'client', command: 'RCPT TO:' }, { timestamp: '14:28:10', direction: 'server', command: '550 5.1.1 The email account that you tried to reach does not exist.', responseCode: 550 }, { timestamp: '14:28:10', direction: 'client', command: 'QUIT' }, { timestamp: '14:28:10', direction: 'server', command: '221 Bye', responseCode: 221 }, ], connectionInfo: { sourceIp: '10.0.1.50', sourceHostname: 'mail.serve.zone', destinationIp: '198.51.100.25', destinationPort: 25, tlsVersion: 'TLSv1.2', tlsCipher: 'ECDHE-RSA-AES128-GCM-SHA256', authenticated: true, authMethod: 'PLAIN', authUser: 'alerts@serve.zone', }, authenticationResults: { spf: 'pass', spfDomain: 'serve.zone', dkim: 'pass', dkimDomain: 'serve.zone', dmarc: 'pass', dmarcPolicy: 'quarantine', }, headers: { 'From': 'alerts@serve.zone', 'To': 'invalid@nowhere.test', 'Subject': 'Service Alert: CPU Usage High', 'Date': 'Mon, 15 Jan 2024 14:28:10 +0000', 'MIME-Version': '1.0', 'Content-Type': 'text/plain; charset=UTF-8', }, body: 'ALERT: CPU Usage High\n\nService: api-gateway\nCurrent Usage: 94.2%\nThreshold: 90%\nTimestamp: 2024-01-15 14:28:00 UTC\n\nPlease investigate immediately.', }, '3': { id: '3', direction: 'inbound', status: 'delivered', from: 'support@customer.com', to: 'admin@serve.zone', toList: ['admin@serve.zone'], cc: ['ops@serve.zone'], subject: 'Re: Infrastructure Review', timestamp: '2024-01-15 14:25:00', messageId: '', size: '24.1 KB', smtpLog: [ { timestamp: '14:24:58', direction: 'client', command: 'EHLO mail.customer.com' }, { timestamp: '14:24:58', direction: 'server', command: '250-mail.serve.zone Hello', responseCode: 250 }, { timestamp: '14:24:58', direction: 'server', command: '250-STARTTLS', responseCode: 250 }, { timestamp: '14:24:58', direction: 'server', command: '250 SIZE 52428800', responseCode: 250 }, { timestamp: '14:24:59', direction: 'client', command: 'STARTTLS' }, { timestamp: '14:24:59', direction: 'server', command: '220 Ready to start TLS', responseCode: 220 }, { timestamp: '14:24:59', direction: 'client', command: 'MAIL FROM:' }, { timestamp: '14:24:59', direction: 'server', command: '250 OK', responseCode: 250 }, { timestamp: '14:24:59', direction: 'client', command: 'RCPT TO:' }, { timestamp: '14:25:00', direction: 'server', command: '250 Accepted', responseCode: 250 }, { timestamp: '14:25:00', direction: 'client', command: 'DATA' }, { timestamp: '14:25:00', direction: 'server', command: '354 Enter message', responseCode: 354 }, { timestamp: '14:25:00', direction: 'client', command: '.' }, { timestamp: '14:25:00', direction: 'server', command: '250 OK id=2bR3sT-0004Cd-E5', responseCode: 250 }, ], connectionInfo: { sourceIp: '203.0.113.45', sourceHostname: 'mail.customer.com', destinationIp: '10.0.1.50', destinationPort: 25, tlsVersion: 'TLSv1.3', tlsCipher: 'TLS_AES_128_GCM_SHA256', authenticated: false, authMethod: '', authUser: '', }, authenticationResults: { spf: 'pass', spfDomain: 'customer.com', dkim: 'pass', dkimDomain: 'customer.com', dmarc: 'pass', dmarcPolicy: 'none', }, headers: { 'From': 'support@customer.com', 'To': 'admin@serve.zone', 'CC': 'ops@serve.zone', 'Subject': 'Re: Infrastructure Review', 'Date': 'Mon, 15 Jan 2024 14:25:00 +0000', 'MIME-Version': '1.0', 'Content-Type': 'text/plain; charset=UTF-8', 'In-Reply-To': '', }, body: 'Hi Admin,\n\nThank you for the detailed infrastructure review report.\n\nWe have reviewed the recommendations and would like to\nproceed with the following:\n\n1. Upgrade to the Pro tier\n2. Enable automatic backups\n3. Set up monitoring alerts\n\nPlease let us know the timeline for these changes.\n\nBest regards,\nCustomer Support Team', }, }; async onActivate(context: { appui: DeesAppui; viewId: string }) { this.appui = context.appui; this.appui.setContentTabs([ { key: 'All Emails', action: () => { this.currentDirectionFilter = 'all'; this.currentView = 'list'; this.updateSecondaryMenu(); }, }, { key: 'Inbound', action: () => { this.currentDirectionFilter = 'inbound'; this.currentView = 'list'; this.updateSecondaryMenu(); }, }, { key: 'Outbound', action: () => { this.currentDirectionFilter = 'outbound'; this.currentView = 'list'; this.updateSecondaryMenu(); }, }, ]); this.updateSecondaryMenu(); } private updateSecondaryMenu() { if (!this.appui) return; this.appui.setSecondaryMenu({ heading: 'Email / MTA', groups: [ { name: 'Actions', items: [ { type: 'action', key: 'Refresh', iconName: 'lucide:RefreshCw', action: () => { console.log('Refresh emails'); } }, { type: 'action', key: 'Export Logs', iconName: 'lucide:Download', action: () => { console.log('Export logs'); } }, ], }, { name: 'Status Filters', items: [ { key: 'Delivered', iconName: 'lucide:CheckCircle', badge: '5', badgeVariant: 'success' as const, action: () => { console.log('Filter delivered'); } }, { key: 'Bounced', iconName: 'lucide:XCircle', badge: '1', badgeVariant: 'error' as const, action: () => { console.log('Filter bounced'); } }, { key: 'Deferred', iconName: 'lucide:Clock', badge: '1', badgeVariant: 'warning' as const, action: () => { console.log('Filter deferred'); } }, { key: 'Pending', iconName: 'lucide:Loader', badge: '1', action: () => { console.log('Filter pending'); } }, ], }, { name: 'Statistics', items: [ { type: 'header' as const, label: '8 Total Emails' }, { type: 'header' as const, label: '62.5% Delivery Rate' }, ], }, ], }); } onDeactivate() { // Cleanup if needed } public static styles = [ cssManager.defaultStyles, css` :host { display: block; padding: 24px; height: 100%; overflow-y: auto; box-sizing: border-box; } `, ]; public render(): TemplateResult { if (this.currentView === 'detail' && this.selectedEmail) { return html` { this.currentView = 'list'; this.selectedEmail = null; }} > `; } return html` e.direction === this.currentDirectionFilter)} @email-click=${(e: CustomEvent) => this.handleEmailClick(e.detail)} > `; } private handleEmailClick(email: IEmail) { const detail = this.demoEmailDetails[email.id]; if (detail) { this.selectedEmail = detail; this.currentView = 'detail'; } else { console.log('No detail data available for email:', email.id); } } }