114 lines
3.6 KiB
Svelte
114 lines
3.6 KiB
Svelte
<script lang="ts">
|
|
import {
|
|
UNIVERSAL_FIELDS,
|
|
getActiveDomainsForEvents,
|
|
type MetadataDomain
|
|
} from '$lib/data/notificationMetadata';
|
|
|
|
interface Props {
|
|
subject: string;
|
|
body: string;
|
|
selectedEventTypes?: string[];
|
|
}
|
|
|
|
let { subject = $bindable(''), body = $bindable(''), selectedEventTypes = [] }: Props = $props();
|
|
|
|
let showVariableHints = $state(false);
|
|
|
|
// Compute active domains based on selected event types
|
|
let activeDomains = $derived<MetadataDomain[]>(getActiveDomainsForEvents(selectedEventTypes));
|
|
|
|
const subjectPlaceholder = 'e.g., New {event_type} notification';
|
|
const bodyPlaceholder = 'e.g., A new {event_type} event occurred for {entity_type} {entity_id}.';
|
|
</script>
|
|
|
|
<div class="space-y-4">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-sm font-medium text-theme">Message Template</h3>
|
|
<button
|
|
type="button"
|
|
onclick={() => (showVariableHints = !showVariableHints)}
|
|
class="text-xs text-primary-600 hover:underline dark:text-primary-400"
|
|
>
|
|
{showVariableHints ? 'Hide' : 'Show'} Variables
|
|
</button>
|
|
</div>
|
|
|
|
{#if showVariableHints}
|
|
<div class="space-y-3 rounded-lg border border-theme bg-theme-card p-3">
|
|
<!-- Universal fields -->
|
|
<div>
|
|
<p class="mb-2 text-xs font-medium text-theme">Universal Variables:</p>
|
|
<div class="flex flex-wrap gap-2">
|
|
{#each UNIVERSAL_FIELDS as field (field.name)}
|
|
<span class="group relative">
|
|
<code
|
|
class="cursor-help rounded bg-primary-500/10 px-1.5 py-0.5 text-xs text-primary-600 dark:text-primary-400"
|
|
>
|
|
{`{${field.name}}`}
|
|
</code>
|
|
<span
|
|
class="absolute bottom-full left-1/2 z-10 mb-1 hidden w-48 -translate-x-1/2 rounded-lg bg-gray-900 px-2 py-1 text-xs text-white group-hover:block"
|
|
>
|
|
{field.description}
|
|
</span>
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Domain-specific fields -->
|
|
{#if activeDomains.length > 0}
|
|
{#each activeDomains as domain (domain.name)}
|
|
<div>
|
|
<p class="mb-2 text-xs font-medium text-theme">{domain.label} Fields:</p>
|
|
<div class="flex flex-wrap gap-2">
|
|
{#each domain.fields as field (field.name)}
|
|
<span class="group relative">
|
|
<code
|
|
class="cursor-help rounded bg-secondary-500/10 px-1.5 py-0.5 text-xs text-secondary-600 dark:text-secondary-400"
|
|
>
|
|
{`{${field.name}}`}
|
|
</code>
|
|
<span
|
|
class="absolute bottom-full left-1/2 z-10 mb-1 hidden w-48 -translate-x-1/2 rounded-lg bg-gray-900 px-2 py-1 text-xs text-white group-hover:block"
|
|
>
|
|
{field.description}
|
|
</span>
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
{:else}
|
|
<p class="text-xs text-theme-muted">
|
|
Select event types above to see available metadata fields.
|
|
</p>
|
|
{/if}
|
|
</div>
|
|
{/if}
|
|
|
|
<div>
|
|
<label for="template-subject" class="mb-1.5 block text-sm font-medium text-theme">Subject</label
|
|
>
|
|
<input
|
|
id="template-subject"
|
|
type="text"
|
|
bind:value={subject}
|
|
placeholder={subjectPlaceholder}
|
|
class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="template-body" class="mb-1.5 block text-sm font-medium text-theme">Body</label>
|
|
<textarea
|
|
id="template-body"
|
|
bind:value={body}
|
|
rows={4}
|
|
placeholder={bodyPlaceholder}
|
|
class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
|
|
></textarea>
|
|
</div>
|
|
</div>
|