feat: add filtering to all entity list pages
- Tracking configs: filter by name + provider type - Template configs: filter by name + provider type - Command configs: filter by name + provider type - Notification trackers: filter by name + provider - Command trackers: filter by name + provider - Targets: filter by name (type filtering already existed) - Nav badge counts include system-owned entities (user_id=0) - Shows "no items match filter" vs "no items yet" empty states
This commit is contained in:
@@ -93,7 +93,11 @@
|
||||
|
||||
let allTargets = $derived(targetsCache.items);
|
||||
let activeType = $derived(page.url.searchParams.get('type') as TargetType | null);
|
||||
let targets = $derived(activeType ? allTargets.filter(t => t.type === activeType) : allTargets);
|
||||
let filterText = $state('');
|
||||
let targets = $derived(allTargets.filter(t =>
|
||||
(!activeType || t.type === activeType) &&
|
||||
(!filterText || t.name.toLowerCase().includes(filterText.toLowerCase()))
|
||||
));
|
||||
let telegramBots = $derived(telegramBotsCache.items);
|
||||
let emailBots = $derived(emailBotsCache.items);
|
||||
let matrixBots = $derived(matrixBotsCache.items);
|
||||
@@ -479,10 +483,21 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if targets.length === 0 && !showForm}
|
||||
{#if !showForm && allTargets.length > 0}
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<input type="text" bind:value={filterText} placeholder={t('common.filterByName')}
|
||||
class="flex-1 px-3 py-1.5 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if allTargets.length === 0 && !showForm}
|
||||
<Card>
|
||||
<EmptyState icon="mdiTarget" message={t('targets.noTargets')} />
|
||||
</Card>
|
||||
{:else if targets.length === 0 && !showForm}
|
||||
<Card>
|
||||
<EmptyState icon="mdiFilterOff" message={t('common.noFilterResults')} />
|
||||
</Card>
|
||||
{:else}
|
||||
<div class="space-y-3 stagger-children">
|
||||
{#each targets as target (target.id)}
|
||||
@@ -547,11 +562,14 @@
|
||||
<div in:slide={{ duration: 150 }} class="mt-2 p-2 rounded-md border border-[var(--color-border)] bg-[var(--color-background)]">
|
||||
{#if target.type === 'telegram'}
|
||||
{@const botId = target.config?.bot_id}
|
||||
{@const existingKeys = new Set((target.receivers || []).map((r: TargetReceiver) => r.receiver_key))}
|
||||
{@const chatItems = (receiverBotChats[botId] || []).map((c: TelegramChat) => ({
|
||||
value: c.chat_id,
|
||||
label: c.title || c.username || c.chat_id,
|
||||
icon: c.type === 'private' ? 'mdiAccount' : c.type === 'channel' ? 'mdiBullhorn' : 'mdiAccountGroup',
|
||||
desc: `${c.type} · ${c.chat_id}`,
|
||||
disabled: existingKeys.has(c.chat_id),
|
||||
disabledHint: existingKeys.has(c.chat_id) ? t('targets.alreadyAdded') : undefined,
|
||||
}))}
|
||||
{#if chatItems.length > 0}
|
||||
<EntitySelect items={chatItems} bind:value={receiverForm.chat_id} placeholder={t('telegramBot.selectChat')} />
|
||||
|
||||
Reference in New Issue
Block a user