From 06b24638cb5f40773694cc2cd9fb8a03f8ec3141 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Sat, 21 Mar 2026 23:44:12 +0300 Subject: [PATCH] feat: IconGridSelect, CrossLink, SearchPalette components + entity crosslinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New components: - IconGridSelect: Visual grid selector replacing + ESC + + +
+ {#if loading} +
+
+ {t('common.loading')} +
+ {:else if flatResults.length === 0} +
+ + {query ? t('searchPalette.noResults') : t('searchPalette.typeToSearch')} +
+ {:else} + {#each groupedResults as group} +
+ + {group.label} +
+ {#each group.items as item, i} + {@const flatIdx = flatResults.indexOf(item)} + + {/each} + {/each} + {/if} +
+ + + +{/if} + + diff --git a/frontend/src/lib/i18n/en.json b/frontend/src/lib/i18n/en.json index 6d99ebf..1b2f9b0 100644 --- a/frontend/src/lib/i18n/en.json +++ b/frontend/src/lib/i18n/en.json @@ -699,5 +699,13 @@ "undefinedVar": "Unknown variable", "line": "line", "add": "Add" + }, + "searchPalette": { + "placeholder": "Search entities...", + "noResults": "No results found", + "typeToSearch": "Start typing to search", + "navigate": "navigate", + "open": "open", + "close": "close" } } \ No newline at end of file diff --git a/frontend/src/lib/i18n/ru.json b/frontend/src/lib/i18n/ru.json index a046749..92f9ee7 100644 --- a/frontend/src/lib/i18n/ru.json +++ b/frontend/src/lib/i18n/ru.json @@ -699,5 +699,13 @@ "undefinedVar": "Неизвестная переменная", "line": "строка", "add": "Добавить" + }, + "searchPalette": { + "placeholder": "Поиск объектов...", + "noResults": "Ничего не найдено", + "typeToSearch": "Начните вводить для поиска", + "navigate": "навигация", + "open": "открыть", + "close": "закрыть" } } \ No newline at end of file diff --git a/frontend/src/lib/stores/caches.svelte.ts b/frontend/src/lib/stores/caches.svelte.ts index f3bf448..84ea118 100644 --- a/frontend/src/lib/stores/caches.svelte.ts +++ b/frontend/src/lib/stores/caches.svelte.ts @@ -9,11 +9,15 @@ import { createEntityCache } from './entity-cache.svelte'; import type { ServiceProvider, NotificationTarget, + Tracker, TrackingConfig, TemplateConfig, TelegramBot, EmailBot, MatrixBot, + CommandConfig, + CommandTemplateConfig, + CommandTracker, } from '$lib/types'; /** Service providers — used by Dashboard, Trackers, Command Trackers, Providers page. */ @@ -22,6 +26,9 @@ export const providersCache = createEntityCache('/providers'); /** Notification targets — used by Trackers, Targets page. */ export const targetsCache = createEntityCache('/targets'); +/** Notification trackers — used by Dashboard, Trackers page. */ +export const notificationTrackersCache = createEntityCache('/notification-trackers'); + /** Tracking configs — used by Trackers, Tracking Configs page. */ export const trackingConfigsCache = createEntityCache('/tracking-configs'); @@ -37,23 +44,42 @@ export const emailBotsCache = createEntityCache('/email-bots'); /** Matrix bots — used by Targets, Bots page. */ export const matrixBotsCache = createEntityCache('/matrix-bots'); -// Command-specific caches (less shared but still benefit from caching) +/** Command configs — used by Command Trackers, Command Configs page. */ +export const commandConfigsCache = createEntityCache('/command-configs'); -export const commandConfigsCache = createEntityCache('/command-configs'); +/** Command template configs — used by Command Configs, Command Template Configs page. */ +export const commandTemplateConfigsCache = createEntityCache('/command-template-configs'); -export const commandTemplateConfigsCache = createEntityCache('/command-template-configs'); +/** Command trackers — used by Command Trackers page. */ +export const commandTrackersCache = createEntityCache('/command-trackers'); + +/** + * All caches keyed by entity type — for search palette and crosslink resolution. + */ +export const allCaches = { + providers: providersCache, + targets: targetsCache, + notification_trackers: notificationTrackersCache, + tracking_configs: trackingConfigsCache, + template_configs: templateConfigsCache, + telegram_bots: telegramBotsCache, + email_bots: emailBotsCache, + matrix_bots: matrixBotsCache, + command_configs: commandConfigsCache, + command_template_configs: commandTemplateConfigsCache, + command_trackers: commandTrackersCache, +} as const; + +/** + * Fetch all caches in parallel. Used by search palette. + */ +export async function fetchAllCaches(): Promise { + await Promise.all(Object.values(allCaches).map(c => c.fetch())); +} /** * Invalidate all entity caches. Useful on logout. */ export function clearAllCaches(): void { - providersCache.clear(); - targetsCache.clear(); - trackingConfigsCache.clear(); - templateConfigsCache.clear(); - telegramBotsCache.clear(); - emailBotsCache.clear(); - matrixBotsCache.clear(); - commandConfigsCache.clear(); - commandTemplateConfigsCache.clear(); + Object.values(allCaches).forEach(c => c.clear()); } diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index 2014026..9780bfe 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -166,6 +166,43 @@ export interface User { created_at: string; } +export interface CommandConfig { + id: number; + user_id: number; + provider_type: string; + name: string; + icon: string; + enabled_commands: string[]; + locale: string; + response_mode: string; + default_count: number; + rate_limits: Record; + command_template_config_id: number | null; + created_at: string; +} + +export interface CommandTemplateConfig { + id: number; + user_id: number; + provider_type: string; + name: string; + description: string; + icon: string; + slots: Record; + created_at: string; +} + +export interface CommandTracker { + id: number; + user_id: number; + name: string; + icon: string; + provider_id: number; + command_config_id: number; + enabled: boolean; + created_at: string; +} + export interface DashboardStatus { providers: number; trackers: { total: number; active: number }; diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 119c747..d99f877 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -11,6 +11,7 @@ import Modal from '$lib/components/Modal.svelte'; import MdiIcon from '$lib/components/MdiIcon.svelte'; import Snackbar from '$lib/components/Snackbar.svelte'; + import SearchPalette from '$lib/components/SearchPalette.svelte'; import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte'; let { children } = $props(); @@ -440,6 +441,7 @@ +