feat: UX improvements — secure webhooks, locale fixes, dynamic languages, UI polish

- Remove top paginator from dashboard events, keep only bottom
- Fix test message locale: pass UI locale to email/matrix bot tests
- Convert webhook auth mode from text input to icon grid selector
- Generate secure UUID tokens for webhook URLs instead of sequential IDs
- Move Recent Payloads into per-provider expandable container (lazy-loaded)
- Make template config languages dynamic via app settings instead of hardcoded
- Change default dev port to 5175
This commit is contained in:
2026-04-11 02:14:15 +03:00
parent 6b2211353d
commit 734e5c9340
29 changed files with 278 additions and 154 deletions
@@ -6,7 +6,9 @@
import IconPicker from '$lib/components/IconPicker.svelte';
import IconGridSelect from '$lib/components/IconGridSelect.svelte';
import { goto } from '$app/navigation';
import { providerTypeItems } from '$lib/grid-items';
import { providerTypeItems, webhookAuthModeItems } from '$lib/grid-items';
const gridItemSources: Record<string, () => any[]> = { webhookAuthModeItems };
import { getDescriptor, buildProviderFormDefaults } from '$lib/providers';
import Button from '$lib/components/Button.svelte';
import ErrorBanner from '$lib/components/ErrorBanner.svelte';
@@ -100,7 +102,9 @@
{t(field.label)}
{#if field.optional}<span class="text-xs text-[var(--color-muted-foreground)]">({t('providers.optional')})</span>{/if}
</label>
{#if field.type === 'number'}
{#if field.type === 'grid-select' && field.gridItems}
<IconGridSelect items={gridItemSources[field.gridItems]()} bind:value={form[field.key]} columns={field.gridColumns ?? 2} compact />
{:else if field.type === 'number'}
<input id="prv-{field.key}" type="number" bind:value={form[field.key]} min={field.min} max={field.max}
class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
{:else}