From 4049efe186fd4e7c986cbcda6f0cc27787cf698b Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Mon, 23 Mar 2026 21:26:49 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20UI=20polish=20=E2=80=94=20overflow,=20pl?= =?UTF-8?q?aceholders,=20dashboard=20provider=20card?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix bot card header overflow by replacing "Sync with Telegram" text button with icon button, add flex-wrap - Rename sync button label to "Sync Commands" - Remove decorative dashes from selector placeholders (— X — → X) - Show selected provider name/icon in dashboard stat card when global provider filter is active - Add selector placeholder convention to frontend-architecture.md --- .claude/docs/frontend-architecture.md | 6 ++++++ CLAUDE.md | 5 +++-- frontend/src/lib/i18n/en.json | 4 ++-- frontend/src/lib/i18n/ru.json | 4 ++-- frontend/src/routes/+page.svelte | 18 +++++++++++++----- frontend/src/routes/bots/TelegramBotTab.svelte | 18 +++++++----------- .../LinkedTargetsSection.svelte | 10 +++++----- 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/.claude/docs/frontend-architecture.md b/.claude/docs/frontend-architecture.md index 8e721e1..9a3af57 100644 --- a/.claude/docs/frontend-architecture.md +++ b/.claude/docs/frontend-architecture.md @@ -42,3 +42,9 @@ Shared entities use a `$state`-based cache layer in `frontend/src/lib/stores/`: 2. Add `export const fooCache = createEntityCache('/foo');` to `caches.svelte.ts` 3. Add `fooCache.clear()` to `clearAllCaches()` 4. In page components: replace `let foo = $state([])` with `let foo = $derived(fooCache.items)` and replace `api('/foo')` with `fooCache.fetch()` + +## UI Conventions + +### Selector Placeholders + +**IMPORTANT**: Selector/dropdown placeholder text must be plain and simple — no decorative dashes or special characters. Use `Select provider...` or `Tracking Configs`, NOT `— Select provider —` or `-- Tracking Configs --`. The i18n keys already follow this convention; never wrap them with `'— ' + t('key') + ' —'` in Svelte templates. diff --git a/CLAUDE.md b/CLAUDE.md index d1656f7..c36b6f5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,8 +16,9 @@ Detailed context is split into focused documents under `.claude/docs/`. Read the 2. **Overlays** MUST use `position: fixed` with inline styles and `z-index: 9999` — see [frontend-architecture.md](.claude/docs/frontend-architecture.md). 3. **Template variables** must be updated in 6 files simultaneously — see [template-system.md](.claude/docs/template-system.md). 4. **Entity cache** — shared entities use `$state`-based caches in `frontend/src/lib/stores/caches.svelte.ts`. Always use cache for cross-page data; invalidate after mutations — see [frontend-architecture.md](.claude/docs/frontend-architecture.md). -5. **Telegram API** — ALL Telegram Bot API calls (sendMessage, sendPhoto, sendMediaGroup, etc.) MUST go through `TelegramClient` in `packages/core/src/notify_bridge_core/notifications/telegram/client.py`. NEVER duplicate sending logic in command handlers, API routes, or services. If `TelegramClient` lacks a method you need, add it there. -6. **Service provider defaults** — when implementing a new service provider, ALWAYS create default notification and command templates and configs. This requires changes across all of these locations: +5. **Selector placeholders** — use plain text without decorative dashes. `Select provider...` not `— Select provider —` — see [frontend-architecture.md](.claude/docs/frontend-architecture.md). +6. **Telegram API** — ALL Telegram Bot API calls (sendMessage, sendPhoto, sendMediaGroup, etc.) MUST go through `TelegramClient` in `packages/core/src/notify_bridge_core/notifications/telegram/client.py`. NEVER duplicate sending logic in command handlers, API routes, or services. If `TelegramClient` lacks a method you need, add it there. +7. **Service provider defaults** — when implementing a new service provider, ALWAYS create default notification and command templates and configs. This requires changes across all of these locations: - Jinja2 notification templates for each locale in `packages/core/src/notify_bridge_core/templates/defaults/{en,ru}/` - Jinja2 command templates for each locale in `packages/core/src/notify_bridge_core/templates/command_defaults/{en,ru}/{provider}/` - Notification slot mapping in `packages/core/src/notify_bridge_core/templates/defaults/loader.py` (`PROVIDER_SLOT_FILE_MAP`) diff --git a/frontend/src/lib/i18n/en.json b/frontend/src/lib/i18n/en.json index 506349f..2621660 100644 --- a/frontend/src/lib/i18n/en.json +++ b/frontend/src/lib/i18n/en.json @@ -330,7 +330,7 @@ "rateFind": "Find cooldown", "rateDefault": "Default cooldown", "noCommandsForProvider": "This provider type does not support bot commands.", - "syncCommands": "Sync with Telegram", + "syncCommands": "Sync Commands", "discoverChats": "Discover chats from Telegram", "clickToCopy": "Click to copy chat ID", "chatsDiscovered": "Chats discovered", @@ -873,7 +873,7 @@ "favoritesOnly": "Favorites only", "targetAlbum": "Target Album", "selectAlbum": "Album", - "selectAlbumPlaceholder": "— Select album —", + "selectAlbumPlaceholder": "Select album", "albumId": "Album ID", "createAlbumIfMissing": "Create album if it doesn't exist", "newAlbumName": "New album name", diff --git a/frontend/src/lib/i18n/ru.json b/frontend/src/lib/i18n/ru.json index a619ad7..fbc8c92 100644 --- a/frontend/src/lib/i18n/ru.json +++ b/frontend/src/lib/i18n/ru.json @@ -330,7 +330,7 @@ "rateFind": "Кулдаун поиска файлов", "rateDefault": "Кулдаун по умолчанию", "noCommandsForProvider": "Этот тип провайдера не поддерживает команды бота.", - "syncCommands": "Синхронизировать с Telegram", + "syncCommands": "Синхр. команды", "discoverChats": "Обнаружить чаты из Telegram", "clickToCopy": "Нажмите, чтобы скопировать ID чата", "chatsDiscovered": "Чаты обнаружены", @@ -873,7 +873,7 @@ "favoritesOnly": "Только избранное", "targetAlbum": "Целевой альбом", "selectAlbum": "Альбом", - "selectAlbumPlaceholder": "— Выберите альбом —", + "selectAlbumPlaceholder": "Выберите альбом", "albumId": "ID альбома", "createAlbumIfMissing": "Создать альбом, если не существует", "newAlbumName": "Название нового альбома", diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index bef4da9..9c130e3 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -177,8 +177,12 @@ let displayCommandTrackers = $state(0); + const filteredProvider = $derived(globalProviderFilter.id ? providers.find(p => p.id === globalProviderFilter.id) : null); + const statCards = $derived(status ? [ - { icon: 'mdiServer', label: 'dashboard.providers', value: displayProviders, color: '#0d9488' }, + filteredProvider + ? { icon: providerDefaultIcon(filteredProvider), label: filteredProvider.name, value: filteredProvider.type, color: '#0d9488', isProvider: true } + : { icon: 'mdiServer', label: 'dashboard.providers', value: displayProviders, color: '#0d9488' }, { icon: 'mdiRadar', label: 'dashboard.activeTrackers', value: displayActive, suffix: ` / ${displayTotal}`, color: '#6366f1' }, { icon: 'mdiTarget', label: 'dashboard.targets', value: displayTargets, color: '#f59e0b' }, ...(status.command_trackers !== undefined ? [{ icon: 'mdiConsoleLine', label: 'nav.commandTrackers', value: displayCommandTrackers, color: '#8b5cf6' }] : []), @@ -234,10 +238,14 @@
-

{t(card.label)}

-

- {card.value}{#if card.suffix}{card.suffix}{/if} -

+

{card.isProvider ? card.label : t(card.label)}

+ {#if card.isProvider} +

{card.value}

+ {:else} +

+ {card.value}{#if card.suffix}{card.suffix}{/if} +

+ {/if}
diff --git a/frontend/src/routes/bots/TelegramBotTab.svelte b/frontend/src/routes/bots/TelegramBotTab.svelte index bf0ede5..1f2b843 100644 --- a/frontend/src/routes/bots/TelegramBotTab.svelte +++ b/frontend/src/routes/bots/TelegramBotTab.svelte @@ -318,9 +318,9 @@
{#each bots as bot} -
-
-
+
+
+

{bot.name}

{#if bot.bot_username} @@ -335,21 +335,17 @@

{bot.token_preview}

-
+
editBot(bot)} /> - + syncCommands(bot.id)} disabled={modeChanging[bot.id]} /> remove(bot.id)} variant="danger" />
diff --git a/frontend/src/routes/notification-trackers/LinkedTargetsSection.svelte b/frontend/src/routes/notification-trackers/LinkedTargetsSection.svelte index 06c15d1..5b39ffd 100644 --- a/frontend/src/routes/notification-trackers/LinkedTargetsSection.svelte +++ b/frontend/src/routes/notification-trackers/LinkedTargetsSection.svelte @@ -85,12 +85,12 @@
onupdateLink(tt, 'tracking_config_id', Number(v) || null)} />
onupdateLink(tt, 'template_config_id', Number(v) || null)} />
@@ -113,17 +113,17 @@
onchangeNewTarget(Number(v) || 0)} />
onchangeNewTrackingConfig(Number(v) || 0)} />
onchangeNewTemplateConfig(Number(v) || 0)} />