Files
shd.build/src/routes/isac/system-messages/+page.svelte
T

51 lines
4.5 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
import PendingForm from '$lib/components/PendingForm.svelte';
let { data, form } = $props();
let editing = $state<any>(null);
let consumedToken = $state<string | null>(null);
const date = (value: unknown) => value ? new Date(String(value)).toLocaleString() : 'NEVER';
const edit = (message: any) => editing = { ...message, actions: [...message.actions, ...Array(Math.max(0, 8 - message.actions.length)).fill(null).map(() => ({ label: '', href: '' }))] };
$effect(() => {
if (form?.messageSaved && form?.resultToken && form.resultToken !== consumedToken) {
consumedToken = form.resultToken;
editing = null;
}
});
</script>
<svelte:head><title>Automated system messages — ISAC</title></svelte:head>
<div class="module-toolbar"><div><p class="eyebrow">SYSTEM CONFIGURATION</p><h2>AUTOMATED MESSAGES</h2><p>Control event-driven ISAC notifications, delivery timing, content, and action callouts.</p></div></div>
<div class="module-kpis"><div><span>DEFINITIONS</span><strong>{data.messages.length}</strong><small>Automated messages</small></div><div><span>ACTIVE</span><strong>{data.messages.filter((item: any) => item.enabled).length}</strong><small>Enabled triggers</small></div><div><span>EVENT TYPES</span><strong>{data.events.length}</strong><small>System lifecycle events</small></div></div>
{#if editing}
<section class="horizontal-editor system-message-editor">
<div class="editor-title"><div><p class="eyebrow">EDIT AUTOMATED MESSAGE</p><h3>{editing.name}</h3></div><button type="button" aria-label="Cancel editing automated message" onclick={() => editing = null}>×</button></div>
<PendingForm action="?/save">
<input type="hidden" name="id" value={editing.id}/>
<div class="system-message-editor-grid">
<label class="field wide">MESSAGE SOURCE<input name="source" value={editing.source} maxlength="80" required/></label>
<label class="field wide">TITLE<input name="title" value={editing.title} maxlength="140" required/></label>
<label class="field event-field">SEND EVENT<input value={data.events.find((event: any) => event.value === editing.event_key)?.label ?? editing.event_key} disabled/><small>{data.events.find((event: any) => event.value === editing.event_key)?.description}</small></label>
<label class="field">DELAY AFTER EVENT · MINUTES<input name="sendDelayMinutes" type="number" min="0" max="10080" step="1" value={editing.send_delay_minutes}/><small>0 sends immediately · maximum 7 days</small></label>
<label class="field system-message-enabled"><span>DELIVERY STATE</span><input name="enabled" type="checkbox" bind:checked={editing.enabled}/><b>{editing.enabled ? 'ENABLED' : 'DISABLED'}</b></label>
<label class="field full">MESSAGE CONTENT<textarea name="body" rows="7" maxlength="2000" required>{editing.body}</textarea></label>
<label class="field full">PRIMARY DESTINATION<input name="link" value={editing.link ?? ''} placeholder="/account"/></label>
</div>
<div class="system-message-actions"><div><span>ACTION CALLOUTS</span><small>Optional internal paths or secure external links · up to 8</small></div>
{#each editing.actions as action, index}
<div><b>{String(index + 1).padStart(2,'0')}</b><input name="actionLabel" value={action.label} placeholder="ACTION LABEL"/><input name="actionHref" value={action.href} placeholder="/destination or https://…"/></div>
{/each}
</div>
{#if form?.messageError}<p class="error">{form.messageError}</p>{/if}
<div class="form-actions"><button type="button" class="secondary" onclick={() => editing = null}>CANCEL</button><button class="primary">SAVE MESSAGE →</button></div>
</PendingForm>
</section>
{/if}
<section class="dashboard-table system-message-table">
<div class="dashboard-row heading"><span>MESSAGE</span><span>TRIGGER</span><span>DELIVERY</span><span>ACTIVITY</span><span></span></div>
{#each data.messages as message}
<div class="dashboard-row"><div><strong>{message.name}</strong><small>{message.description}</small></div><div><strong>{data.events.find((event: any) => event.value === message.event_key)?.label ?? message.event_key}</strong><small>{message.enabled ? 'ENABLED' : 'DISABLED'}</small></div><div><strong>{Number(message.send_delay_minutes) ? `${message.send_delay_minutes} MIN DELAY` : 'IMMEDIATE'}</strong><small>{message.title}</small></div><div><strong>{message.delivery_count} SENT</strong><small>LAST · {date(message.last_delivered_at)}</small></div><button class="table-action" onclick={() => edit(message)}>EDIT →</button></div>
{/each}
</section>