feat: locale-aware notification templates + UX improvements

- Add locale support to notification templates (matching command template
  pattern): TemplateSlot now has locale field with (config_id, slot_name,
  locale) uniqueness, nested API format {slot: {locale: template}}
- Migration merges separate EN/RU system configs into unified per-provider
  configs; seeds create one config per provider with multi-locale slots
- Locale-aware dispatch with EN fallback in NotificationDispatcher
- Frontend locale tabs (EN/RU) on template config editor
- Fix tracking config cards not showing default provider icons
- Global provider filter, search palette, and various UX polish
This commit is contained in:
2026-03-23 19:08:48 +03:00
parent 6a559bfcd2
commit 37388c430c
30 changed files with 628 additions and 318 deletions
@@ -213,14 +213,15 @@ class TemplateConfig(SQLModel, table=True):
class TemplateSlot(SQLModel, table=True):
"""One Jinja2 template for a specific slot within a TemplateConfig.
"""One Jinja2 template for a specific slot and locale within a TemplateConfig.
Slot names are provider-specific (e.g. 'message_assets_added' for Immich).
Each (config, slot, locale) triple holds a separate template.
"""
__tablename__ = "template_slot"
__table_args__ = (
UniqueConstraint("config_id", "slot_name", name="uq_template_slot"),
UniqueConstraint("config_id", "slot_name", "locale", name="uq_template_slot_locale"),
)
id: int | None = Field(default=None, primary_key=True)
@@ -231,6 +232,7 @@ class TemplateSlot(SQLModel, table=True):
)
slot_name: str
locale: str = Field(default="en")
template: str = Field(default="", sa_column=Column(Text, default=""))