feat: replace all select dropdowns with IconGridSelect, fix EN template seed

Shared grid-items.ts with reusable item definitions for: sort by/order,
album mode, asset type, memory source, locale, response mode, event type
filter, chat action, preview target type, provider type.

Replaced selects on:
- Dashboard: event type, provider, sort (compact mode — auto-width)
- Tracking configs: sort by/order, album modes, asset types, memory source
- Command configs: locale, response mode, provider type
- Targets: chat action
- Template configs: preview target type, provider type
- Command template configs: provider type
- Providers: type selector (read-only during edit)

IconGridSelect: added compact prop for inline filter bars (auto-width,
smaller padding, shows icon + label text).

Backend: template seed now re-creates deleted system templates on startup
using raw SQL to handle legacy NOT NULL columns.

Added i18n: trackingConfig.providerType, trackingConfig.sortRandom
Added provider_type badge to tracking config cards.
This commit is contained in:
2026-03-22 01:17:06 +03:00
parent db7aac5fe8
commit a9bb912c30
11 changed files with 175 additions and 104 deletions
@@ -13,10 +13,7 @@
import IconButton from '$lib/components/IconButton.svelte';
import CrossLink from '$lib/components/CrossLink.svelte';
import IconGridSelect from '$lib/components/IconGridSelect.svelte';
const providerTypeItems = [
{ value: 'immich', icon: 'mdiCamera', label: 'Immich' },
];
import { providerTypeItems, localeItems, responseModeItems } from '$lib/grid-items';
import EntitySelect from '$lib/components/EntitySelect.svelte';
import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
import { highlightFromUrl } from '$lib/highlight';
@@ -169,7 +166,7 @@
<div>
<label class="block text-sm font-medium mb-1">{t('commandConfig.providerType')}</label>
{#if !editing}
<IconGridSelect items={providerTypeItems} bind:value={form.provider_type} columns={2} />
<IconGridSelect items={providerTypeItems()} bind:value={form.provider_type} columns={2} />
{:else}
<p class="text-sm text-[var(--color-muted-foreground)]">{form.provider_type}</p>
{/if}
@@ -198,19 +195,11 @@
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3">
<div>
<label class="block text-xs mb-1">{t('commandConfig.locale')}</label>
<select bind:value={form.locale}
class="w-full px-2 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
<option value="en">English</option>
<option value="ru">Русский</option>
</select>
<IconGridSelect items={localeItems()} bind:value={form.locale} columns={2} />
</div>
<div>
<label class="block text-xs mb-1">{t('commandConfig.responseMode')}</label>
<select bind:value={form.response_mode}
class="w-full px-2 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
<option value="media">{t('commandConfig.modeMedia')}</option>
<option value="text">{t('commandConfig.modeText')}</option>
</select>
<IconGridSelect items={responseModeItems(t)} bind:value={form.response_mode} columns={2} />
</div>
<div>
<label class="block text-xs mb-1">{t('commandConfig.defaultCount')}</label>