feat(elements): standardize dashboard and detail views on dees tile and stats grid components

This commit is contained in:
2026-04-07 22:27:23 +00:00
parent b91d3a9341
commit 9aad9c0c2a
16 changed files with 1148 additions and 972 deletions

View File

@@ -256,31 +256,89 @@ export class SzMtaDetailView extends DeesElement {
gap: 24px;
}
.card {
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
border-radius: 8px;
overflow: hidden;
.card-header {
height: 36px;
display: flex;
align-items: center;
padding: 0 16px;
width: 100%;
box-sizing: border-box;
}
.card-header {
.card-heading {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
align-items: baseline;
gap: 8px;
min-width: 0;
}
.card-title {
font-size: 16px;
font-weight: 600;
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
font-weight: 500;
font-size: 13px;
letter-spacing: -0.01em;
color: var(--dees-color-text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-subtitle {
font-size: 13px;
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
margin-top: 2px;
font-size: 12px;
color: var(--dees-color-text-muted);
letter-spacing: -0.01em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-footer {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: 0;
height: 36px;
width: 100%;
box-sizing: border-box;
}
.tile-button {
padding: 0 16px;
height: 100%;
text-align: center;
font-size: 12px;
font-weight: 500;
cursor: pointer;
user-select: none;
transition: all 0.15s ease;
background: transparent;
border: none;
border-left: 1px solid var(--dees-color-border-subtle);
color: var(--dees-color-text-muted);
white-space: nowrap;
display: flex;
align-items: center;
gap: 6px;
}
.tile-button:first-child {
border-left: none;
}
.tile-button:hover {
background: var(--dees-color-hover);
color: var(--dees-color-text-primary);
}
.tile-button.primary {
color: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8%)', 'hsl(213.1 93.9% 67.8%)')};
font-weight: 600;
}
.tile-button.primary:hover {
background: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8% / 0.08)', 'hsl(213.1 93.9% 67.8% / 0.08)')};
color: ${cssManager.bdTheme('hsl(217.2 91.2% 50%)', 'hsl(213.1 93.9% 75%)')};
}
.card-content {
@@ -451,37 +509,13 @@ export class SzMtaDetailView extends DeesElement {
color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
}
/* Copy button */
.smtp-copy-button {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border-radius: 6px;
border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
background: transparent;
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 150ms ease;
}
.smtp-copy-button:hover {
background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
color: ${cssManager.bdTheme('#18181b', '#fafafa')};
border-color: ${cssManager.bdTheme('#d4d4d8', '#3f3f46')};
}
/* Header subtitle enhancements */
/* SMTP metadata banner — sits inside content, above the log */
.smtp-header-subtitle {
font-size: 13px;
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
margin-top: 2px;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
padding: 10px 16px;
font-size: 12px;
color: var(--dees-color-text-muted);
border-bottom: 1px solid var(--dees-color-border-subtle);
font-family: monospace;
}
.smtp-direction-badge {
@@ -578,7 +612,7 @@ export class SzMtaDetailView extends DeesElement {
color: ${cssManager.bdTheme('#ca8a04', '#facc15')};
}
.rejection-card {
dees-tile.rejection-card::part(outer) {
border-color: ${cssManager.bdTheme('#fecaca', 'rgba(239, 68, 68, 0.3)')};
}
@@ -646,9 +680,11 @@ export class SzMtaDetailView extends DeesElement {
<div class="content">
<div class="main-content">
<!-- Email Metadata -->
<div class="card">
<div class="card-header">
<div class="card-title">Email Metadata</div>
<dees-tile>
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">Email Metadata</span>
</div>
</div>
<div class="card-content">
<div class="detail-list">
@@ -684,49 +720,53 @@ export class SzMtaDetailView extends DeesElement {
</div>
</div>
</div>
</div>
</dees-tile>
<!-- SMTP Transaction Log -->
<div class="card">
<div class="card-header">
<div>
<div class="card-title">SMTP Transaction Log</div>
<div class="smtp-header-subtitle">
<span class="smtp-direction-badge ${email.direction}">${email.direction}</span>
<span>${email.direction === 'outbound'
? `${email.connectionInfo.sourceHostname}${email.connectionInfo.destinationIp}:${email.connectionInfo.destinationPort}`
: `${email.connectionInfo.sourceIp}${email.connectionInfo.sourceHostname}:${email.connectionInfo.destinationPort}`
}</span>
</div>
<dees-tile>
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">SMTP Transaction Log</span>
<span class="smtp-direction-badge ${email.direction}">${email.direction}</span>
</div>
<button class="smtp-copy-button" @click=${() => this.copySmtpLog()}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
</div>
<div class="smtp-header-subtitle">
${email.direction === 'outbound'
? `${email.connectionInfo.sourceHostname}${email.connectionInfo.destinationIp}:${email.connectionInfo.destinationPort}`
: `${email.connectionInfo.sourceIp}${email.connectionInfo.sourceHostname}:${email.connectionInfo.destinationPort}`
}
</div>
${this.renderSmtpLog(email)}
<div slot="footer" class="card-footer">
<button class="tile-button" @click=${() => this.copySmtpLog()}>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
Copy Log
</button>
</div>
${this.renderSmtpLog(email)}
</div>
</dees-tile>
<!-- Email Body -->
<div class="card">
<div class="card-header">
<div>
<div class="card-title">Email Body (Escaped)</div>
<div class="card-subtitle">Raw content — HTML is not rendered</div>
<dees-tile>
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">Email Body (Escaped)</span>
<span class="card-subtitle">Raw content — HTML is not rendered</span>
</div>
</div>
<pre class="email-body-container">${email.body}</pre>
</div>
</dees-tile>
</div>
<div class="sidebar">
<!-- Connection Info -->
<div class="card">
<div class="card-header">
<div class="card-title">Connection Info</div>
<dees-tile>
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">Connection Info</span>
</div>
</div>
<div class="card-content">
<div class="detail-list">
@@ -772,12 +812,14 @@ export class SzMtaDetailView extends DeesElement {
` : ''}
</div>
</div>
</div>
</dees-tile>
<!-- Authentication Results -->
<div class="card">
<div class="card-header">
<div class="card-title">Authentication Results</div>
<dees-tile>
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">Authentication Results</span>
</div>
</div>
<div class="card-content">
<div class="auth-row">
@@ -802,13 +844,15 @@ export class SzMtaDetailView extends DeesElement {
<span class="auth-badge ${email.authenticationResults.dmarc}">${email.authenticationResults.dmarc}</span>
</div>
</div>
</div>
</dees-tile>
<!-- Rejection Details (conditional) -->
${email.status === 'rejected' || email.status === 'bounced' ? html`
<div class="card rejection-card">
<div class="card-header">
<div class="card-title">Rejection Details</div>
<dees-tile class="rejection-card">
<div slot="header" class="card-header">
<div class="card-heading">
<span class="card-title">Rejection Details</span>
</div>
</div>
<div class="card-content">
${email.rejectionReason ? html`
@@ -820,7 +864,7 @@ export class SzMtaDetailView extends DeesElement {
<div class="rejection-text">${email.bounceMessage}</div>
` : ''}
</div>
</div>
</dees-tile>
` : ''}
</div>
</div>