fix: re-create missing EN default template, provider type as IconGridSelect

- Template seed now re-creates missing system templates on every startup
  (not just first boot), using raw SQL to handle legacy NOT NULL columns
- Tracking configs: add provider type selector (was missing)
- All config forms: provider type uses IconGridSelect during creation,
  read-only text during editing (immutable after creation)
- Pages: tracking-configs, command-configs, command-template-configs,
  template-configs
This commit is contained in:
2026-03-22 00:36:15 +03:00
parent 9d3abd9fa0
commit db7aac5fe8
@@ -93,6 +93,7 @@ async def _seed_default_templates():
Uses TemplateSlot child rows for template content. Uses TemplateSlot child rows for template content.
""" """
from sqlalchemy import text
from sqlmodel import func, select from sqlmodel import func, select
from sqlmodel.ext.asyncio.session import AsyncSession from sqlmodel.ext.asyncio.session import AsyncSession
from .database.engine import get_engine from .database.engine import get_engine
@@ -101,43 +102,70 @@ async def _seed_default_templates():
engine = get_engine() engine = get_engine()
async with AsyncSession(engine) as session: async with AsyncSession(engine) as session:
result = await session.exec(select(func.count()).select_from(TemplateConfig)) # Find existing system-owned templates
count = result.one()
if count == 0:
# First startup — seed all defaults
for locale in ("en", "ru"):
slots = load_default_templates(locale)
if not slots:
continue
name = f"Default ({locale.upper()})"
config = TemplateConfig(
user_id=0,
provider_type="immich",
name=name,
description=f"Default Immich templates ({locale.upper()})",
)
session.add(config)
await session.flush() # get config.id
for slot_name, template_text in slots.items():
session.add(TemplateSlot(
config_id=config.id,
slot_name=slot_name,
template=template_text,
))
else:
# Update existing system-owned templates from files
result = await session.exec( result = await session.exec(
select(TemplateConfig).where(TemplateConfig.user_id == 0) select(TemplateConfig).where(TemplateConfig.user_id == 0)
) )
system_configs = result.all() system_configs = result.all()
for config in system_configs: existing_locales = {
locale = "ru" if "(RU)" in config.name else "en" "ru" if "(RU)" in c.name else "en": c for c in system_configs
}
for locale in ("en", "ru"):
slots = load_default_templates(locale) slots = load_default_templates(locale)
if not slots: if not slots:
continue continue
if locale not in existing_locales:
# Create missing system template via raw SQL
# (legacy NOT NULL columns may still exist in the DB)
name = f"Default ({locale.upper()})"
desc = f"Default Immich templates ({locale.upper()})"
# Get column names to build INSERT with defaults for legacy cols
col_info = (await session.execute(
text("PRAGMA table_info(template_config)")
)).fetchall()
col_names = [c[1] for c in col_info if c[1] != "id"]
values = {}
from datetime import datetime, timezone
now = datetime.now(timezone.utc).isoformat()
for col in col_names:
if col == "user_id":
values[col] = 0
elif col == "provider_type":
values[col] = "immich"
elif col == "name":
values[col] = name
elif col == "description":
values[col] = desc
elif col == "created_at":
values[col] = now
elif col == "date_format":
values[col] = "%d.%m.%Y, %H:%M UTC"
elif col == "date_only_format":
values[col] = "%d.%m.%Y"
else:
values[col] = "" # empty string for legacy columns
cols_str = ", ".join(values.keys())
placeholders = ", ".join(f":{k}" for k in values.keys())
await session.execute(
text(f"INSERT INTO template_config ({cols_str}) VALUES ({placeholders})"),
values,
)
# Get the inserted ID
row = (await session.execute(text("SELECT last_insert_rowid()"))).scalar()
config_id = row
for slot_name, template_text in slots.items():
session.add(TemplateSlot(
config_id=config_id,
slot_name=slot_name,
template=template_text,
))
else:
# Update existing system template slots
config = existing_locales[locale]
for slot_name, template_text in slots.items(): for slot_name, template_text in slots.items():
# Upsert: find existing slot or create new
slot_result = await session.exec( slot_result = await session.exec(
select(TemplateSlot).where( select(TemplateSlot).where(
TemplateSlot.config_id == config.id, TemplateSlot.config_id == config.id,