feat: chat language display, disabled EntitySelect items, dev scripts

Chat language:
- Added language_code field to TelegramChat model + migration
- Saved from message.from.language_code on webhook/polling
- Displayed as badge on bot chat cards and target receiver items
- Resolved from DB in target API response (works for existing receivers)
- Shown in chat picker dropdown (desc includes language)

EntitySelect improvements:
- Tracker-target link selector shows all targets, already-linked ones
  appear disabled with "Already linked" hint
- Receiver chat picker shows already-added chats as disabled

Dev scripts:
- scripts/restart-backend.sh and restart-frontend.sh
- Updated .claude/docs/dev-servers.md to reference scripts
This commit is contained in:
2026-03-22 23:39:52 +03:00
parent e90c128dca
commit 82e400ddcd
16 changed files with 161 additions and 122 deletions
@@ -429,7 +429,7 @@
{tracker}
{trackingConfigs}
{templateConfigs}
unlinkedTargets={getUnlinkedTargets(tracker)}
unlinkedTargets={targets}
newLinkTargetId={newLinkTargetId[tracker.id] || 0}
newLinkTrackingConfigId={newLinkTrackingConfigId[tracker.id] || 0}
newLinkTemplateConfigId={newLinkTemplateConfigId[tracker.id] || 0}
@@ -57,11 +57,14 @@
const trackingConfigItems = $derived(toItems(trackingConfigs));
const templateConfigItems = $derived(toItems(templateConfigs));
const linkedTargetIds = $derived(new Set((tracker.tracker_targets || []).map((tt: any) => tt.target_id)));
const targetItems = $derived<EntityItem[]>(unlinkedTargets.map(tgt => ({
value: tgt.id,
label: tgt.name,
icon: tgt.icon || (tgt.type === 'telegram' ? 'mdiSend' : 'mdiWebhook'),
desc: tgt.type,
disabled: linkedTargetIds.has(tgt.id),
disabledHint: linkedTargetIds.has(tgt.id) ? t('notificationTracker.alreadyLinked') : undefined,
})));
</script>