feat: EntitySelect palette-style entity picker, replace select dropdowns
New EntitySelect component: modal palette with search, keyboard nav, current-value indicator (left border), smooth overlay. Replaces native <select> dropdowns for entity selection. Replaced selects: - Notification Trackers: provider selector - Command Trackers: provider + command config selectors - Command Configs: response template selector - Targets: telegram bot, email bot, matrix bot selectors Added reactive $effect watchers for loadCollections and loadBotChats since EntitySelect uses bind:value instead of onchange.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
import ConfirmModal from '$lib/components/ConfirmModal.svelte';
|
||||
import IconButton from '$lib/components/IconButton.svelte';
|
||||
import CrossLink from '$lib/components/CrossLink.svelte';
|
||||
import EntitySelect from '$lib/components/EntitySelect.svelte';
|
||||
import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
|
||||
import { highlightFromUrl } from '$lib/highlight';
|
||||
import type { ServiceProvider, TelegramBot } from '$lib/types';
|
||||
@@ -21,6 +22,9 @@
|
||||
let providers = $derived(providersCache.items);
|
||||
let commandConfigs = $derived(commandConfigsCache.items);
|
||||
let telegramBots = $derived(telegramBotsCache.items);
|
||||
const providerItems = $derived(providers.map(p => ({ value: p.id, label: p.name, icon: p.icon || 'mdiServer', desc: p.type })));
|
||||
const configItems = $derived(filteredConfigs().map((c: any) => ({ value: c.id, label: c.name, icon: c.icon || 'mdiCog', desc: c.provider_type })));
|
||||
const botItems = $derived(telegramBots.map(b => ({ value: b.id, label: b.name, icon: b.icon || 'mdiRobot', desc: b.bot_username ? `@${b.bot_username}` : '' })));
|
||||
let loaded = $state(false);
|
||||
let showForm = $state(false);
|
||||
let editing = $state<number | null>(null);
|
||||
@@ -191,25 +195,13 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="trk-provider" class="block text-sm font-medium mb-1">{t('commandTracker.provider')}</label>
|
||||
<select id="trk-provider" bind:value={form.provider_id} required
|
||||
class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
|
||||
<option value={0} disabled>{t('commandTracker.selectProvider')}</option>
|
||||
{#each providers as p}
|
||||
<option value={p.id}>{p.name} ({p.type})</option>
|
||||
{/each}
|
||||
</select>
|
||||
<label class="block text-sm font-medium mb-1">{t('commandTracker.provider')}</label>
|
||||
<EntitySelect items={providerItems} bind:value={form.provider_id} placeholder={t('commandTracker.selectProvider')} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="trk-config" class="block text-sm font-medium mb-1">{t('commandTracker.commandConfig')}</label>
|
||||
<select id="trk-config" bind:value={form.command_config_id} required
|
||||
class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
|
||||
<option value={0} disabled>{t('commandTracker.selectCommandConfig')}</option>
|
||||
{#each filteredConfigs() as c}
|
||||
<option value={c.id}>{c.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<label class="block text-sm font-medium mb-1">{t('commandTracker.commandConfig')}</label>
|
||||
<EntitySelect items={configItems} bind:value={form.command_config_id} placeholder={t('commandTracker.selectCommandConfig')} />
|
||||
</div>
|
||||
|
||||
<button type="submit" disabled={submitting}
|
||||
|
||||
Reference in New Issue
Block a user