- Preview button always visible next to Variables for each template slot
- Remove \n\n prefix from video_warning default value
- Use conditional {% if video_warning %} with blank line in templates
- Fix all .jinja2 files and inline defaults to match
- Add SVG favicon (camera + notification dot)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Audit and fix all template variable references:
- template_vars.py: Add missing fields (album_id, old_shared,
new_shared, latitude, longitude, owner_id, people per asset)
- _SAMPLE_CONTEXT: Use proper structured data matching
build_asset_detail() output (id, owner_id, latitude, longitude,
people per asset, playback_url for videos)
- i18n: Fix all variable descriptions for accuracy, add missing
fields, mark scheduler-dependent slots as "not yet implemented"
- Variables modal: Add album_fields section for periodic_summary
- Shared _ASSET_FIELDS and _ALBUM_FIELDS dicts in template_vars.py
to keep scheduled/memory slots DRY
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Preview now piggybacks on the validation debounce call — when the
template renders successfully, the result is shown in a collapsible
<details> section below the editor. Removes the manual Preview button
since it's now automatic. Preview hides when there are errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two-pass validation in preview-raw endpoint:
1. Syntax check (catches {% if %}, unclosed tags)
2. StrictUndefined render (catches {{ asset.a }}, {{ bad_var }})
Frontend shows:
- Red error for syntax errors with line number
- Amber warning for undefined variables
- Error line highlighted in editor
Sample context now uses proper structured data (lists of dicts
for assets/albums) so valid field access like {{ asset.filename }}
renders correctly during preview.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validates template syntax as user types (800ms debounce). Calls
preview-raw API and shows red error text below the editor if
Jinja2 parsing fails. Clears error when template is valid.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JinjaEditor:
- Custom StreamLanguage parser for Jinja2 syntax highlighting:
{{ variables }} in blue, {% statements %} in purple, {# comments #} in gray
- Replaced HTML mode (didn't understand Jinja2 syntax)
- Proper monospace font (Consolas/Monaco)
TemplateConfig:
- Added `description` field to model + seed defaults with descriptions
- Description shown on template cards instead of raw template text
- Description input in create/edit form
Preview:
- Toggle behavior: clicking Preview again hides the preview
- Per-slot preview uses preview-raw API (renders current editor content)
i18n: added common.description, templateConfig.descriptionPlaceholder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each template slot now has its own Preview button next to the label.
Clicking it renders the current editor content via preview-raw API
and shows the result inline below the editor. Removed the old
per-card preview dropdown since preview is now part of editing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Modal: revert to inline styles (Tailwind fixed class broken).
Added max-height: 80vh with overflow-y: auto for scrollable content.
- Template configs: preview is now per message slot via dropdown
(assets added/removed/renamed/deleted, periodic, scheduled, memory)
instead of hardcoded to assets_added only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Escape {{ }} in Svelte template (use {'{{ }}'} string expression)
- Allow _get() to access system templates (user_id=0) for preview
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major template system overhaul:
- TemplateConfig simplified from 21 fields to 9: removed all sub-templates
(asset_image, asset_video, assets_format, people_format, etc.)
Users write full Jinja2 with {% for %}, {% if %} inline.
- Default EN/RU templates seeded on first startup (user_id=0, system-owned)
with proper Jinja2 loops over added_assets, people, albums.
- build_full_context() simplified: passes raw data directly to Jinja2
instead of pre-rendering sub-templates.
- CodeMirror editor for template slots (HTML syntax highlighting,
line wrapping, dark theme support via oneDark).
- Variable reference API: GET /api/template-configs/variables returns
per-slot variable descriptions + asset_fields for loop contexts.
- Variable reference modal in UI: click "{{ }} Variables" next to any
slot to see available variables with Jinja2 syntax examples.
- Route ordering fix: /variables registered before /{config_id}.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create Hint component with fixed-position floating tooltip
- Add hints to tracking configs (periodic/scheduled/memory modes,
favorites, times, album mode, rating), template configs (section
legends), targets (AI captions, media settings, config selectors),
and trackers (scan interval)
- Add 21 hint i18n keys in EN and RU
- Fix transition:slide → in:slide on all pages to prevent content
overlap when navigating away mid-animation
- Merge Asset Display into Event Tracking fieldset; use consistent
"Max Assets" label with hint in each section
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: Fix CORS wildcard+credentials, add secret key warning, remove raw
API keys from sync endpoint, fix N+1 queries in watcher/sync, fix
AttributeError on event_types, delete dead scheduled.py/templates.py,
add limit cap on history, re-validate server on URL/key update, apply
tracking/template config IDs in update_target.
HA Integration: Replace datetime.now() with dt_util.now(), fix notification
queue to only remove successfully sent items, use album UUID for entity
unique IDs, add shared links dirty flag and users cache hourly refresh,
deduplicate _is_quiet_hours, add HTTP timeouts, cache albums in config
flow, change iot_class to local_polling.
Frontend: Make i18n reactive via $state (remove window.location.reload),
add Modal transitions/a11y/Escape key, create ConfirmModal replacing all
confirm() calls, add error handling to all pages, replace Unicode nav
icons with MDI SVGs, add card hover effects, dashboard stat icons, global
focus-visible styles, form slide transitions, mobile responsive bottom
nav, fix password error color, add ~20 i18n keys (EN/RU).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Install @mdi/js (~7000 Material Design Icons)
- IconPicker component: dropdown with search, popular icons grid,
clear option. Stores icon name as string (e.g. "mdiCamera")
- MdiIcon component: renders SVG from icon name
- Backend: add `icon` field to ImmichServer, TelegramBot,
TrackingConfig, TemplateConfig, NotificationTarget, AlbumTracker
- All 6 entity pages: icon picker next to name input in create/edit
forms, icon displayed on entity cards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New pages:
- /tracking-configs: Full CRUD with event tracking, asset display,
periodic summary, scheduled assets, and memory mode sections.
Collapsible sub-sections that show/hide based on enabled state.
- /template-configs: Full CRUD with all 21 template slots organized
into 5 fieldsets (event messages, asset formatting, date/location,
scheduled messages, telegram). Preview support per slot.
Updated pages:
- Targets: added tracking_config_id + template_config_id selectors
(dropdowns populated from configs). Configs are reusable.
- Trackers: simplified to album selection + scan interval + targets.
Added Test, Test Periodic, Test Memory buttons per tracker.
- Nav: replaced Templates with Tracking + Templates config links
Other fixes:
- Language button: now triggers window.location.reload() to force
all child pages to re-evaluate t() calls
- Dark theme buttons: changed primary color to dark gray in dark mode
- Removed old /templates page (replaced by /template-configs)
- Added .gitignore for __pycache__ in server package
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>