Menu
Public repository / 10d19fe0941c186ec244d1f0e2af6b19200dcb0c
AkurAI-Mail / src/lib/webmail/SignalBadge.svelte
Latest change ecdd82c68dc11022c41dbf1ff22cac68e002a3e1 - OLI-247: wave 2 — signal-badge view model and signals-based sync state on framework runtime by Ólafur Búi Ólafsson
<script lang="ts">
import { Bell, Clock, Flag, MessageCircle } from "lucide-svelte";
import { signalLabel, signalColorClass, unansweredAgeLabel } from "../../framework/signal-badge.js";
let { signalType, signal, onCorrect, onDismiss, convId, compact = false }: {
signalType: string;
signal: any;
onCorrect?: (convId: string, type: string, action: string, value?: any) => void;
onDismiss?: (convId: string, type: string, action: string) => void;
convId: string;
compact?: boolean;
} = $props();
const dismissed = $derived(signal?.dismissed ?? false);
function iconFor(type: string) {
if (type === "replyNeeded") return MessageCircle;
if (type === "followUpDue") return Clock;
if (type === "priority") return Flag;
return Bell;
}
</script>
{#if signal && !dismissed}
<span class="signal-badge {signalColorClass(signalType, signal?.value)}" class:compact title={signal?.evidence?.join("; ") ?? ""}>
{#if compact}
{@const Icon = iconFor(signalType)}
<Icon size={13} strokeWidth={2} />
{:else}
{@const Icon = iconFor(signalType)}
<Icon size={14} strokeWidth={2} />
<span>{signalLabel(signalType, signal)}</span>
{#if signalType === "replyNeeded" && signal?.unansweredAge}
<em>{unansweredAgeLabel(signal.unansweredAge)}</em>
{/if}
{#if onDismiss}
<button class="signal-dismiss" aria-label="Dismiss" onclick={() => onDismiss(convId, signalType, "dismiss")}>×</button>
{/if}
{/if}
</span>
{/if}
<style>
.signal-badge {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 12px;
font-weight: 600;
padding: 3px 8px;
border-radius: 5px;
line-height: 1;
white-space: nowrap;
}
.signal-badge.compact {
padding: 2px 4px;
gap: 0;
border-radius: 4px;
min-width: 0;
}
.signal-amber {
background: #fff7e0;
color: #9a6b00;
border: 1px solid #f0d060;
}
.signal-blue {
background: #e8f0fe;
color: #1a56b4;
border: 1px solid #b8d4f8;
}
.signal-red {
background: #fdecea;
color: #b3261e;
border: 1px solid #f5c6c2;
}
.signal-muted {
background: #f3f4f6;
color: #61716c;
border: 1px solid #dce4e1;
}
.signal-badge em {
font-style: normal;
opacity: 0.7;
margin-left: 1px;
}
.signal-dismiss {
border: 0;
background: none;
color: inherit;
cursor: pointer;
padding: 0 2px;
margin-left: 2px;
font-size: 15px;
line-height: 1;
opacity: 0.5;
}
.signal-dismiss:hover {
opacity: 1;
}
</style>