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.
"""
from sqlalchemy import text
from sqlmodel import func, select
from sqlmodel.ext.asyncio.session import AsyncSession
from .database.engine import get_engine
@@ -101,43 +102,70 @@ async def _seed_default_templates():
engine = get_engine()
async with AsyncSession(engine) as session:
result = await session.exec(select(func.count()).select_from(TemplateConfig))
count = result.one()
# Find existing system-owned templates
result = await session.exec(
select(TemplateConfig).where(TemplateConfig.user_id == 0)
)
system_configs = result.all()
existing_locales = {
"ru" if "(RU)" in c.name else "en": c for c in system_configs
}
if count == 0:
# First startup — seed all defaults
for locale in ("en", "ru"):
slots = load_default_templates(locale)
if not slots:
continue
for locale in ("en", "ru"):
slots = load_default_templates(locale)
if not slots:
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()})"
config = TemplateConfig(
user_id=0,
provider_type="immich",
name=name,
description=f"Default Immich templates ({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,
)
session.add(config)
await session.flush() # get config.id
# 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,
config_id=config_id,
slot_name=slot_name,
template=template_text,
))
else:
# Update existing system-owned templates from files
result = await session.exec(
select(TemplateConfig).where(TemplateConfig.user_id == 0)
)
system_configs = result.all()
for config in system_configs:
locale = "ru" if "(RU)" in config.name else "en"
slots = load_default_templates(locale)
if not slots:
continue
else:
# Update existing system template slots
config = existing_locales[locale]
for slot_name, template_text in slots.items():
# Upsert: find existing slot or create new
slot_result = await session.exec(
select(TemplateSlot).where(
TemplateSlot.config_id == config.id,