feat: step 6 first round

This commit is contained in:
2026-04-28 20:38:26 +02:00
parent 0f3c1e12c1
commit 0929a4e798
12 changed files with 3072 additions and 141 deletions

View File

@@ -65,6 +65,10 @@
"translationValidation.fix": "Probleme beheben",
"translationValidation.toast.fixSuccess": "%{dbRows} DB-Zeilen und %{files} Dateien gelöscht, %{flushed} Übersetzungen auf Datenträger geschrieben",
"chat.newChat": "Neuer Chat",
"chat.setupTitle": "KI-Chat-Einrichtung",
"chat.apiKeyRequiredTitle": "API-Schlüssel erforderlich",
"chat.apiKeyRequiredDescription": "Konfiguriere einen API-Schlüssel in den Einstellungen, um den KI-Chat zu aktivieren.",
"chat.openSettings": "Einstellungen öffnen",
"chat.welcomeTitle": "Willkommen beim KI-Assistenten",
"chat.welcomeDescription": "Ich kann dir mit interaktiven Visualisierungen bei deinem Blog helfen. Frag mich zum Beispiel nach:",
"chat.welcomeTipSearch": "Beiträgen zu einem bestimmten Thema",
@@ -75,6 +79,8 @@
"chat.role.you": "Du",
"chat.role.assistant": "Assistent",
"chat.inputPlaceholder": "Nachricht eingeben...",
"chat.stop": "Stopp",
"chat.cancelledSuffix": "(abgebrochen)",
"gitDiff.changedFiles": "Geänderte Dateien",
"sidebar.tags": "Schlagwörter",
"sidebar.categories": "Kategorien",

View File

@@ -65,6 +65,10 @@
"translationValidation.fix": "Fix Issues",
"translationValidation.toast.fixSuccess": "Deleted %{dbRows} DB rows and %{files} files, flushed %{flushed} translations to disk",
"chat.newChat": "New Chat",
"chat.setupTitle": "AI Chat Setup",
"chat.apiKeyRequiredTitle": "API Key Required",
"chat.apiKeyRequiredDescription": "Configure an API key in Settings to enable AI chat.",
"chat.openSettings": "Open Settings",
"chat.welcomeTitle": "Welcome to the AI Assistant",
"chat.welcomeDescription": "I can help you manage your blog with rich visualizations. Try asking me to:",
"chat.welcomeTipSearch": "Search for posts about a specific topic",
@@ -75,6 +79,8 @@
"chat.role.you": "You",
"chat.role.assistant": "Assistant",
"chat.inputPlaceholder": "Type a message...",
"chat.stop": "Stop",
"chat.cancelledSuffix": "(cancelled)",
"gitDiff.changedFiles": "Changed files",
"sidebar.tags": "Tags",
"sidebar.categories": "Categories",

View File

@@ -65,6 +65,10 @@
"translationValidation.fix": "Corregir problemas",
"translationValidation.toast.fixSuccess": "%{dbRows} filas de BD y %{files} archivos eliminados, %{flushed} traducciones escritas a disco",
"chat.newChat": "Nuevo chat",
"chat.setupTitle": "Configuración de chat IA",
"chat.apiKeyRequiredTitle": "Clave API requerida",
"chat.apiKeyRequiredDescription": "Configura una clave API en Ajustes para habilitar el chat de IA.",
"chat.openSettings": "Abrir Ajustes",
"chat.welcomeTitle": "Bienvenido al asistente de IA",
"chat.welcomeDescription": "Puedo ayudarte a gestionar tu blog con visualizaciones interactivas. Prueba a pedirme que:",
"chat.welcomeTipSearch": "Busque entradas sobre un tema específico",
@@ -75,6 +79,8 @@
"chat.role.you": "Tú",
"chat.role.assistant": "Asistente",
"chat.inputPlaceholder": "Escribe un mensaje...",
"chat.stop": "Detener",
"chat.cancelledSuffix": "(cancelado)",
"gitDiff.changedFiles": "Archivos modificados",
"sidebar.tags": "Etiquetas",
"sidebar.categories": "Categorías",

View File

@@ -67,6 +67,10 @@
"chat.newChat": "Nouveau chat",
"chat.welcomeTitle": "Bienvenue dans lassistant IA",
"chat.welcomeDescription": "Je peux vous aider à gérer votre blog avec des visualisations riches. Essayez par exemple :",
"chat.setupTitle": "Configuration du chat IA",
"chat.apiKeyRequiredTitle": "Clé API requise",
"chat.apiKeyRequiredDescription": "Configurez une clé API dans les Réglages pour activer le chat IA.",
"chat.openSettings": "Ouvrir les Réglages",
"chat.welcomeTipSearch": "Rechercher des articles sur un sujet précis",
"chat.welcomeTipChart": "Afficher un graphique des articles publiés par mois",
"chat.welcomeTipTable": "Comparer mes derniers articles dans un tableau",
@@ -75,6 +79,8 @@
"chat.role.you": "Vous",
"chat.role.assistant": "Assistant IA",
"chat.inputPlaceholder": "Saisissez un message...",
"chat.stop": "Arrêter",
"chat.cancelledSuffix": "(annulé)",
"gitDiff.changedFiles": "Fichiers modifiés",
"sidebar.tags": "Étiquettes",
"sidebar.categories": "Catégories",

View File

@@ -65,6 +65,10 @@
"translationValidation.fix": "Correggi problemi",
"translationValidation.toast.fixSuccess": "%{dbRows} righe DB e %{files} file eliminati, %{flushed} traduzioni scritte su disco",
"chat.newChat": "Nuova chat",
"chat.setupTitle": "Configurazione chat IA",
"chat.apiKeyRequiredTitle": "Chiave API richiesta",
"chat.apiKeyRequiredDescription": "Configura una chiave API nelle Impostazioni per abilitare la chat IA.",
"chat.openSettings": "Apri Impostazioni",
"chat.welcomeTitle": "Benvenuto nellassistente IA",
"chat.welcomeDescription": "Posso aiutarti a gestire il tuo blog con visualizzazioni interattive. Prova a chiedermi di:",
"chat.welcomeTipSearch": "Cercare post su un argomento specifico",
@@ -75,6 +79,8 @@
"chat.role.you": "Tu",
"chat.role.assistant": "Assistente",
"chat.inputPlaceholder": "Scrivi un messaggio...",
"chat.stop": "Ferma",
"chat.cancelledSuffix": "(annullato)",
"gitDiff.changedFiles": "File modificati",
"sidebar.tags": "Tag",
"sidebar.categories": "Categorie",

File diff suppressed because it is too large Load Diff

View File

@@ -683,6 +683,113 @@ document.addEventListener("DOMContentLoaded", () => {
}
},
ChatSurface: {
mounted() {
this.stickToBottom = true;
this.scrollContainer = null;
this.autoResize = () => {
const textarea = this.el.querySelector(".chat-input");
if (!textarea) {
return;
}
textarea.style.height = "auto";
textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
};
this.syncScrollContainer = () => {
const nextContainer = this.el.querySelector(".chat-messages");
if (nextContainer === this.scrollContainer) {
return;
}
if (this.scrollContainer) {
this.scrollContainer.removeEventListener("scroll", this.handleScroll);
}
this.scrollContainer = nextContainer;
if (this.scrollContainer) {
this.scrollContainer.addEventListener("scroll", this.handleScroll);
}
};
this.scrollToBottom = (force = false) => {
if (!this.scrollContainer) {
return;
}
if (force || this.stickToBottom) {
this.scrollContainer.scrollTop = this.scrollContainer.scrollHeight;
}
};
this.handleScroll = () => {
if (!this.scrollContainer) {
this.stickToBottom = true;
return;
}
const distanceFromBottom =
this.scrollContainer.scrollHeight -
this.scrollContainer.scrollTop -
this.scrollContainer.clientHeight;
this.stickToBottom = distanceFromBottom < 48;
};
this.handleInput = (event) => {
if (!event.target.closest(".chat-input")) {
return;
}
this.stickToBottom = true;
this.autoResize();
};
this.handleKeyDown = (event) => {
if (!event.target.closest(".chat-input")) {
return;
}
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
event.preventDefault();
const sendButton = this.el.querySelector("[data-testid='chat-send-button']");
if (sendButton && !sendButton.disabled) {
sendButton.click();
}
}
};
this.el.addEventListener("input", this.handleInput);
this.el.addEventListener("keydown", this.handleKeyDown);
this.syncScrollContainer();
this.autoResize();
window.requestAnimationFrame(() => this.scrollToBottom(true));
},
updated() {
this.syncScrollContainer();
this.autoResize();
window.requestAnimationFrame(() => this.scrollToBottom());
},
destroyed() {
this.el.removeEventListener("input", this.handleInput);
this.el.removeEventListener("keydown", this.handleKeyDown);
if (this.scrollContainer) {
this.scrollContainer.removeEventListener("scroll", this.handleScroll);
}
}
},
MonacoEditor: {
mounted() {
this.textarea = document.getElementById(this.el.dataset.monacoInputId) || this.el.querySelector("textarea");