51 lines
4.5 KiB
Svelte
51 lines
4.5 KiB
Svelte
<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>
|