refactor: comprehensive consistency review — UI/UX, code quality, functional parity
Fix 19 issues across 3 priority tiers found during full-codebase review: CRITICAL: - Fix undefined --color-secondary CSS variable causing invisible UI elements - Fix Google Photos command templates using nonexistent asset.originalFileName - Fix scheduler template variable docs (tracker_name → schedule_name) - Add missing admin guard on notification template update endpoint HIGH: - Fix 5 hardcoded English strings missing i18n (MultiEntitySelect, actions, settings, TelegramBotTab, users) - Replace 17 raw <button> elements with shared <Button> component - Replace 5 raw error divs with shared <ErrorBanner> component - Refactor webhook handler duplication into shared _dispatch_webhook_event() - Add 30+ provider-specific fields to TrackingConfig TypeScript type - Add default TrackingConfig seeds for immich and google_photos - Add provider-specific command variable docs (Gitea, Planka, NUT, GP, Webhook) MEDIUM: - Replace hardcoded hex colors and Tailwind classes with CSS variable tokens - Remove dead code (unused imports, orphaned check_notification_tracker) - Fix Svelte 5 patterns ($state for _prevProviderId, remove unnecessary as any) - Fix inconsistent POST response shape (targets now returns full response) - Fix Google Photos template dead asset.year branches, clarify album_url docs
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
import { highlightFromUrl } from '$lib/highlight';
|
||||
import { globalProviderFilter } from '$lib/stores/provider-filter.svelte';
|
||||
import { providerDefaultIcon } from '$lib/grid-items';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import type { ServiceProvider, TelegramBot } from '$lib/types';
|
||||
|
||||
let allCmdTrackers = $state<any[]>([]);
|
||||
@@ -186,10 +187,9 @@
|
||||
</script>
|
||||
|
||||
<PageHeader title={t('commandTracker.title')} description={t('commandTracker.description')}>
|
||||
<button onclick={() => { showForm ? (showForm = false, editing = null) : openNew(); }}
|
||||
class="px-3 py-1.5 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
|
||||
<Button size="sm" onclick={() => { showForm ? (showForm = false, editing = null) : openNew(); }}>
|
||||
{showForm ? t('common.cancel') : t('commandTracker.newTracker')}
|
||||
</button>
|
||||
</Button>
|
||||
</PageHeader>
|
||||
|
||||
{#if !loaded}<Loading />{:else}
|
||||
@@ -217,10 +217,9 @@
|
||||
<EntitySelect items={configItems} bind:value={form.command_config_id} placeholder={t('commandTracker.selectCommandConfig')} />
|
||||
</div>
|
||||
|
||||
<button type="submit" disabled={submitting}
|
||||
class="px-4 py-2 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90 disabled:opacity-50">
|
||||
<Button type="submit" disabled={submitting}>
|
||||
{submitting ? t('common.loading') : (editing ? t('common.save') : t('common.create'))}
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
</Card>
|
||||
{/if}
|
||||
@@ -257,8 +256,8 @@
|
||||
<CrossLink href="/providers" icon="mdiServer" label={providerName(trk.provider_id)} entityId={trk.provider_id} />
|
||||
<CrossLink href="/command-configs" icon="mdiCog" label={configName(trk.command_config_id)} entityId={trk.command_config_id} />
|
||||
<span class="text-xs px-1.5 py-0.5 rounded font-mono {trk.enabled
|
||||
? 'bg-emerald-500/10 text-emerald-500'
|
||||
: 'bg-red-500/10 text-red-500'}">
|
||||
? 'bg-[var(--color-success-bg)] text-[var(--color-success-fg)]'
|
||||
: 'bg-[var(--color-error-bg)] text-[var(--color-error-fg)]'}">
|
||||
{trk.enabled ? t('commandTracker.enabled') : t('commandTracker.disabled')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -293,7 +292,7 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<MdiIcon name="mdiRobot" size={14} />
|
||||
<CrossLink href="/bots?tab=telegram" icon="mdiRobot" label={listener.name || listener.listener_type} entityId={listener.listener_id} />
|
||||
<span class="text-xs px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-500 font-mono">{listener.listener_type}</span>
|
||||
<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-primary)]/10 text-[var(--color-primary)] font-mono">{listener.listener_type}</span>
|
||||
</div>
|
||||
<IconButton icon="mdiClose" title={t('commandTracker.removeListener')} size={14}
|
||||
onclick={() => removeListener(trk.id, listener.id)} variant="danger" />
|
||||
@@ -307,10 +306,9 @@
|
||||
<div class="flex-1">
|
||||
<EntitySelect items={botItems} bind:value={newListenerBotId[trk.id]} placeholder={t('commandTracker.selectBot')} />
|
||||
</div>
|
||||
<button onclick={() => addListener(trk.id)} disabled={!newListenerBotId[trk.id] || addingListener[trk.id]}
|
||||
class="text-xs px-3 py-1 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md hover:opacity-90 disabled:opacity-50">
|
||||
<Button size="sm" onclick={() => addListener(trk.id)} disabled={!newListenerBotId[trk.id] || addingListener[trk.id]}>
|
||||
{addingListener[trk.id] ? t('common.loading') : t('commandTracker.addListener')}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user