feat: step 5 claimed done
This commit is contained in:
@@ -45,6 +45,37 @@
|
||||
"render.video.vimeoTitle": "Vimeo-Video",
|
||||
"render.video.youtubeTitle": "YouTube-Video",
|
||||
"sidebar.chat.yesterday": "Gestern",
|
||||
"translationValidation.title": "Übersetzungen validieren",
|
||||
"translationValidation.summary": "Geprüfte DB-Zeilen: %{dbRows} · Geprüfte Dateien: %{files} · Ungültige DB-Zeilen: %{invalidDb} · Ungültige Dateien: %{invalidFiles}",
|
||||
"translationValidation.databaseTitle": "Ungültige Übersetzungszeilen in der Datenbank",
|
||||
"translationValidation.filesystemTitle": "Ungültige Übersetzungsdateien auf dem Datenträger",
|
||||
"translationValidation.noneDatabase": "Keine ungültigen Übersetzungszeilen gefunden.",
|
||||
"translationValidation.noneFilesystem": "Keine ungültigen Übersetzungsdateien gefunden.",
|
||||
"translationValidation.issue.sameLanguage": "Übersetzungssprache entspricht der kanonischen Beitragssprache",
|
||||
"translationValidation.issue.missingSource": "Übersetzung verweist auf einen fehlenden Quellbeitrag",
|
||||
"translationValidation.issue.doNotTranslate": "Beitrag ist als nicht-übersetzen markiert, hat aber Übersetzungen",
|
||||
"translationValidation.issue.contentInDatabase": "Veröffentlichte Übersetzung hat Inhalt in der DB statt im Dateisystem",
|
||||
"translationValidation.field.translationFor": "Quellbeitrag",
|
||||
"translationValidation.field.translationId": "Übersetzungszeile",
|
||||
"translationValidation.field.title": "Titel",
|
||||
"translationValidation.field.languages": "Sprachen",
|
||||
"translationValidation.field.filePath": "Datei",
|
||||
"translationValidation.languagesWithCanonical": "%{canonical} = %{translation}",
|
||||
"translationValidation.revalidate": "Erneut validieren",
|
||||
"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.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",
|
||||
"chat.welcomeTipChart": "einem Diagramm der pro Monat veröffentlichten Beiträge",
|
||||
"chat.welcomeTipTable": "einem Tabellenvergleich meiner letzten Beiträge",
|
||||
"chat.welcomeTipMetadata": "Metadaten für Beiträge oder Medien",
|
||||
"chat.welcomeTipTabs": "Beitragsstatistiken pro Jahr in Tabs mit Diagrammen",
|
||||
"chat.role.you": "Du",
|
||||
"chat.role.assistant": "Assistent",
|
||||
"chat.inputPlaceholder": "Nachricht eingeben...",
|
||||
"gitDiff.changedFiles": "Geänderte Dateien",
|
||||
"sidebar.tags": "Schlagwörter",
|
||||
"sidebar.categories": "Kategorien",
|
||||
"sidebar.clearTags": "Tags löschen",
|
||||
|
||||
@@ -45,6 +45,37 @@
|
||||
"render.video.vimeoTitle": "Vimeo video",
|
||||
"render.video.youtubeTitle": "YouTube video",
|
||||
"sidebar.chat.yesterday": "Yesterday",
|
||||
"translationValidation.title": "Validate Translations",
|
||||
"translationValidation.summary": "Checked DB rows: %{dbRows} · Checked files: %{files} · Invalid DB rows: %{invalidDb} · Invalid files: %{invalidFiles}",
|
||||
"translationValidation.databaseTitle": "Invalid database translation rows",
|
||||
"translationValidation.filesystemTitle": "Invalid translation files on disk",
|
||||
"translationValidation.noneDatabase": "No invalid translation rows found.",
|
||||
"translationValidation.noneFilesystem": "No invalid translation files found.",
|
||||
"translationValidation.issue.sameLanguage": "Translation language matches canonical post language",
|
||||
"translationValidation.issue.missingSource": "Translation points to a missing source post",
|
||||
"translationValidation.issue.doNotTranslate": "Post is marked as do-not-translate but has translations",
|
||||
"translationValidation.issue.contentInDatabase": "Published translation has content stuck in DB instead of filesystem",
|
||||
"translationValidation.field.translationFor": "Source post",
|
||||
"translationValidation.field.translationId": "Translation row",
|
||||
"translationValidation.field.title": "Title",
|
||||
"translationValidation.field.languages": "Languages",
|
||||
"translationValidation.field.filePath": "File",
|
||||
"translationValidation.languagesWithCanonical": "%{canonical} = %{translation}",
|
||||
"translationValidation.revalidate": "Revalidate",
|
||||
"translationValidation.fix": "Fix Issues",
|
||||
"translationValidation.toast.fixSuccess": "Deleted %{dbRows} DB rows and %{files} files, flushed %{flushed} translations to disk",
|
||||
"chat.newChat": "New Chat",
|
||||
"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",
|
||||
"chat.welcomeTipChart": "Show a chart of posts published per month",
|
||||
"chat.welcomeTipTable": "Compare my recent posts in a table",
|
||||
"chat.welcomeTipMetadata": "Update metadata for posts or media",
|
||||
"chat.welcomeTipTabs": "Show post statistics by year in tabs with charts",
|
||||
"chat.role.you": "You",
|
||||
"chat.role.assistant": "Assistant",
|
||||
"chat.inputPlaceholder": "Type a message...",
|
||||
"gitDiff.changedFiles": "Changed files",
|
||||
"sidebar.tags": "Tags",
|
||||
"sidebar.categories": "Categories",
|
||||
"sidebar.clearTags": "Clear tags",
|
||||
|
||||
@@ -45,6 +45,37 @@
|
||||
"render.video.vimeoTitle": "Vídeo de Vimeo",
|
||||
"render.video.youtubeTitle": "Vídeo de YouTube",
|
||||
"sidebar.chat.yesterday": "Ayer",
|
||||
"translationValidation.title": "Validar traducciones",
|
||||
"translationValidation.summary": "Filas de BD revisadas: %{dbRows} · Archivos revisados: %{files} · Filas de BD inválidas: %{invalidDb} · Archivos inválidos: %{invalidFiles}",
|
||||
"translationValidation.databaseTitle": "Filas de traducción inválidas en la base de datos",
|
||||
"translationValidation.filesystemTitle": "Archivos de traducción inválidos en disco",
|
||||
"translationValidation.noneDatabase": "No se encontraron filas de traducción inválidas.",
|
||||
"translationValidation.noneFilesystem": "No se encontraron archivos de traducción inválidos.",
|
||||
"translationValidation.issue.sameLanguage": "El idioma de la traducción coincide con el idioma canónico de la entrada",
|
||||
"translationValidation.issue.missingSource": "La traducción apunta a una entrada de origen inexistente",
|
||||
"translationValidation.issue.doNotTranslate": "La entrada está marcada como no-traducir pero tiene traducciones",
|
||||
"translationValidation.issue.contentInDatabase": "Traducción publicada con contenido en la BD en lugar del sistema de archivos",
|
||||
"translationValidation.field.translationFor": "Entrada de origen",
|
||||
"translationValidation.field.translationId": "Fila de traducción",
|
||||
"translationValidation.field.title": "Título",
|
||||
"translationValidation.field.languages": "Idiomas",
|
||||
"translationValidation.field.filePath": "Archivo",
|
||||
"translationValidation.languagesWithCanonical": "%{canonical} = %{translation}",
|
||||
"translationValidation.revalidate": "Revalidar",
|
||||
"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.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",
|
||||
"chat.welcomeTipChart": "Muestre un gráfico de entradas publicadas por mes",
|
||||
"chat.welcomeTipTable": "Compare mis entradas recientes en una tabla",
|
||||
"chat.welcomeTipMetadata": "Actualice metadatos de entradas o medios",
|
||||
"chat.welcomeTipTabs": "Muestre estadísticas por año en pestañas con gráficos",
|
||||
"chat.role.you": "Tú",
|
||||
"chat.role.assistant": "Asistente",
|
||||
"chat.inputPlaceholder": "Escribe un mensaje...",
|
||||
"gitDiff.changedFiles": "Archivos modificados",
|
||||
"sidebar.tags": "Etiquetas",
|
||||
"sidebar.categories": "Categorías",
|
||||
"sidebar.clearTags": "Limpiar etiquetas",
|
||||
|
||||
@@ -45,6 +45,37 @@
|
||||
"render.video.vimeoTitle": "Vidéo Vimeo",
|
||||
"render.video.youtubeTitle": "Vidéo YouTube",
|
||||
"sidebar.chat.yesterday": "Hier",
|
||||
"translationValidation.title": "Valider les traductions",
|
||||
"translationValidation.summary": "Lignes BD vérifiées : %{dbRows} · Fichiers vérifiés : %{files} · Lignes BD invalides : %{invalidDb} · Fichiers invalides : %{invalidFiles}",
|
||||
"translationValidation.databaseTitle": "Lignes de traduction invalides dans la base de données",
|
||||
"translationValidation.filesystemTitle": "Fichiers de traduction invalides sur le disque",
|
||||
"translationValidation.noneDatabase": "Aucune ligne de traduction invalide trouvée.",
|
||||
"translationValidation.noneFilesystem": "Aucun fichier de traduction invalide trouvé.",
|
||||
"translationValidation.issue.sameLanguage": "La langue de traduction correspond à la langue canonique de l’article",
|
||||
"translationValidation.issue.missingSource": "La traduction pointe vers un article source manquant",
|
||||
"translationValidation.issue.doNotTranslate": "L'article est marqué ne-pas-traduire mais a des traductions",
|
||||
"translationValidation.issue.contentInDatabase": "Traduction publiée avec contenu encore en base au lieu du système de fichiers",
|
||||
"translationValidation.field.translationFor": "Article source",
|
||||
"translationValidation.field.translationId": "Ligne de traduction",
|
||||
"translationValidation.field.title": "Titre",
|
||||
"translationValidation.field.languages": "Langues",
|
||||
"translationValidation.field.filePath": "Fichier",
|
||||
"translationValidation.languagesWithCanonical": "%{canonical} = %{translation}",
|
||||
"translationValidation.revalidate": "Revalider",
|
||||
"translationValidation.fix": "Corriger les problèmes",
|
||||
"translationValidation.toast.fixSuccess": "%{dbRows} lignes DB et %{files} fichiers supprimés, %{flushed} traductions écrites sur disque",
|
||||
"chat.newChat": "Nouveau chat",
|
||||
"chat.welcomeTitle": "Bienvenue dans l’assistant IA",
|
||||
"chat.welcomeDescription": "Je peux vous aider à gérer votre blog avec des visualisations riches. Essayez par exemple :",
|
||||
"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",
|
||||
"chat.welcomeTipMetadata": "Mettre à jour les métadonnées des articles ou médias",
|
||||
"chat.welcomeTipTabs": "Afficher les statistiques par année dans des onglets avec graphiques",
|
||||
"chat.role.you": "Vous",
|
||||
"chat.role.assistant": "Assistant IA",
|
||||
"chat.inputPlaceholder": "Saisissez un message...",
|
||||
"gitDiff.changedFiles": "Fichiers modifiés",
|
||||
"sidebar.tags": "Étiquettes",
|
||||
"sidebar.categories": "Catégories",
|
||||
"sidebar.clearTags": "Effacer les étiquettes",
|
||||
|
||||
@@ -45,6 +45,37 @@
|
||||
"render.video.vimeoTitle": "Video Vimeo",
|
||||
"render.video.youtubeTitle": "Video YouTube",
|
||||
"sidebar.chat.yesterday": "Ieri",
|
||||
"translationValidation.title": "Valida traduzioni",
|
||||
"translationValidation.summary": "Righe DB controllate: %{dbRows} · File controllati: %{files} · Righe DB non valide: %{invalidDb} · File non validi: %{invalidFiles}",
|
||||
"translationValidation.databaseTitle": "Righe di traduzione non valide nel database",
|
||||
"translationValidation.filesystemTitle": "File di traduzione non validi sul disco",
|
||||
"translationValidation.noneDatabase": "Nessuna riga di traduzione non valida trovata.",
|
||||
"translationValidation.noneFilesystem": "Nessun file di traduzione non valido trovato.",
|
||||
"translationValidation.issue.sameLanguage": "La lingua della traduzione coincide con la lingua canonica del post",
|
||||
"translationValidation.issue.missingSource": "La traduzione punta a un post sorgente mancante",
|
||||
"translationValidation.issue.doNotTranslate": "Il post è contrassegnato come non-tradurre ma ha traduzioni",
|
||||
"translationValidation.issue.contentInDatabase": "Traduzione pubblicata con contenuto nel DB invece del filesystem",
|
||||
"translationValidation.field.translationFor": "Post sorgente",
|
||||
"translationValidation.field.translationId": "Riga traduzione",
|
||||
"translationValidation.field.title": "Titolo",
|
||||
"translationValidation.field.languages": "Lingue",
|
||||
"translationValidation.field.filePath": "File",
|
||||
"translationValidation.languagesWithCanonical": "%{canonical} = %{translation}",
|
||||
"translationValidation.revalidate": "Rivalidare",
|
||||
"translationValidation.fix": "Correggi problemi",
|
||||
"translationValidation.toast.fixSuccess": "%{dbRows} righe DB e %{files} file eliminati, %{flushed} traduzioni scritte su disco",
|
||||
"chat.newChat": "Nuova chat",
|
||||
"chat.welcomeTitle": "Benvenuto nell’assistente 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",
|
||||
"chat.welcomeTipChart": "Mostrare un grafico dei post pubblicati per mese",
|
||||
"chat.welcomeTipTable": "Confrontare i miei post recenti in una tabella",
|
||||
"chat.welcomeTipMetadata": "Aggiornare i metadati di post o media",
|
||||
"chat.welcomeTipTabs": "Mostrare statistiche per anno in schede con grafici",
|
||||
"chat.role.you": "Tu",
|
||||
"chat.role.assistant": "Assistente",
|
||||
"chat.inputPlaceholder": "Scrivi un messaggio...",
|
||||
"gitDiff.changedFiles": "File modificati",
|
||||
"sidebar.tags": "Tag",
|
||||
"sidebar.categories": "Categorie",
|
||||
"sidebar.clearTags": "Cancella tag",
|
||||
|
||||
198
priv/ui/app.css
198
priv/ui/app.css
@@ -3272,6 +3272,57 @@ button svg * {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.chat-panel-header {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chat-panel-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.chat-model-selector-button,
|
||||
.chat-model-selector-option {
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 10px;
|
||||
background: var(--panel-2, #252526);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.chat-model-selector-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.chat-model-selector-menu {
|
||||
position: absolute;
|
||||
top: calc(100% - 4px);
|
||||
right: 20px;
|
||||
min-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 12px;
|
||||
background: var(--panel-1, #1e1e1e);
|
||||
box-shadow: 0 14px 36px rgba(0, 0, 0, 0.28);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.chat-model-selector-option {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.chat-model-selector-option.active {
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
@@ -3300,6 +3351,56 @@ button svg * {
|
||||
background: rgba(0, 122, 204, 0.15);
|
||||
}
|
||||
|
||||
.chat-tool-markers {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.chat-tool-marker {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.chat-tool-surface {
|
||||
max-width: min(820px, 100%);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 14px;
|
||||
background: var(--panel-2, #252526);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.chat-tool-surface h3 {
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
.chat-tool-surface-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.chat-tool-surface-table th,
|
||||
.chat-tool-surface-table td {
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid var(--line, #3c3c3c);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.chat-tool-surface-json {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
font: 12px/1.5 "SFMono-Regular", Menlo, Monaco, Consolas, monospace;
|
||||
}
|
||||
|
||||
.chat-input-container {
|
||||
padding: 16px 20px 20px;
|
||||
border-top: 1px solid var(--line, #3c3c3c);
|
||||
@@ -3436,6 +3537,103 @@ button svg * {
|
||||
font: 12px/1.5 "SFMono-Regular", Menlo, Monaco, Consolas, monospace;
|
||||
}
|
||||
|
||||
.translation-validation-view,
|
||||
.git-diff-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.translation-validation-summary,
|
||||
.translation-validation-section,
|
||||
.git-diff-toolbar {
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 12px;
|
||||
background: var(--panel-2, #252526);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.translation-validation-summary p,
|
||||
.git-diff-empty {
|
||||
margin: 0;
|
||||
color: var(--vscode-descriptionForeground);
|
||||
}
|
||||
|
||||
.translation-validation-list {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.translation-validation-card {
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 12px;
|
||||
background: var(--panel-1, #1e1e1e);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.translation-validation-card-title {
|
||||
margin: 0 0 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.translation-validation-card-meta {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(120px, 180px) minmax(0, 1fr);
|
||||
gap: 8px 12px;
|
||||
}
|
||||
|
||||
.translation-validation-card-meta dt {
|
||||
color: var(--vscode-descriptionForeground);
|
||||
}
|
||||
|
||||
.translation-validation-card-meta dd {
|
||||
margin: 0;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.translation-validation-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.translation-validation-empty {
|
||||
margin: 12px 0 0;
|
||||
color: var(--vscode-descriptionForeground);
|
||||
}
|
||||
|
||||
.git-diff-toolbar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.git-diff-toolbar label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.git-diff-toolbar select {
|
||||
min-width: min(420px, 100%);
|
||||
}
|
||||
|
||||
.git-diff-editor {
|
||||
flex: 1;
|
||||
min-height: 420px;
|
||||
border: 1px solid var(--line, #3c3c3c);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: var(--panel-1, #1e1e1e);
|
||||
}
|
||||
|
||||
.monaco-diff-editor-instance {
|
||||
height: 100%;
|
||||
min-height: 420px;
|
||||
}
|
||||
|
||||
.linkish {
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
133
priv/ui/live.js
133
priv/ui/live.js
@@ -238,6 +238,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
|
||||
const diffModelPath = (filePath, side) => {
|
||||
const normalized = String(filePath || "working-tree").replace(/^\/+/, "");
|
||||
return `inmemory://model/git-diff/${side}/${normalized}`;
|
||||
};
|
||||
|
||||
const registerLiquidLanguage = (monaco) => {
|
||||
if (liquidLanguageRegistered) {
|
||||
return;
|
||||
@@ -826,6 +831,134 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
this.changeSubscription?.dispose();
|
||||
this.editor?.dispose();
|
||||
}
|
||||
},
|
||||
|
||||
MonacoDiffEditor: {
|
||||
mounted() {
|
||||
this.host = this.el.querySelector(".monaco-diff-editor-instance");
|
||||
this.originalInput = this.el.querySelector(".monaco-diff-original");
|
||||
this.modifiedInput = this.el.querySelector(".monaco-diff-modified");
|
||||
this.filePath = this.el.dataset.monacoDiffFilePath || "working-tree";
|
||||
this.language = this.el.dataset.monacoDiffLanguage || "plaintext";
|
||||
this.viewStyle = this.el.dataset.monacoDiffViewStyle || "inline";
|
||||
this.wordWrap = this.el.dataset.monacoDiffWordWrap || "off";
|
||||
this.hideUnchanged = this.el.dataset.monacoDiffHideUnchanged === "true";
|
||||
|
||||
this.readValues = () => ({
|
||||
original: this.originalInput?.value || "",
|
||||
modified: this.modifiedInput?.value || ""
|
||||
});
|
||||
|
||||
this.applyDataset = () => {
|
||||
this.filePath = this.el.dataset.monacoDiffFilePath || "working-tree";
|
||||
this.language = this.el.dataset.monacoDiffLanguage || "plaintext";
|
||||
this.viewStyle = this.el.dataset.monacoDiffViewStyle || "inline";
|
||||
this.wordWrap = this.el.dataset.monacoDiffWordWrap || "off";
|
||||
this.hideUnchanged = this.el.dataset.monacoDiffHideUnchanged === "true";
|
||||
};
|
||||
|
||||
this.setModels = (monaco) => {
|
||||
const values = this.readValues();
|
||||
|
||||
this.originalModel?.dispose();
|
||||
this.modifiedModel?.dispose();
|
||||
|
||||
this.originalModel = monaco.editor.createModel(
|
||||
values.original,
|
||||
this.language,
|
||||
monaco.Uri.parse(diffModelPath(this.filePath, "original"))
|
||||
);
|
||||
|
||||
this.modifiedModel = monaco.editor.createModel(
|
||||
values.modified,
|
||||
this.language,
|
||||
monaco.Uri.parse(diffModelPath(this.filePath, "modified"))
|
||||
);
|
||||
|
||||
this.editor.setModel({ original: this.originalModel, modified: this.modifiedModel });
|
||||
this.lastFilePath = this.filePath;
|
||||
};
|
||||
|
||||
loadMonaco()
|
||||
.then((monaco) => {
|
||||
if (!this.host) {
|
||||
return;
|
||||
}
|
||||
|
||||
ensureMonacoTheme(monaco);
|
||||
|
||||
this.editor = monaco.editor.createDiffEditor(this.host, {
|
||||
theme: "bds-theme",
|
||||
automaticLayout: true,
|
||||
readOnly: true,
|
||||
renderSideBySide: this.viewStyle === "side-by-side",
|
||||
minimap: { enabled: false },
|
||||
scrollBeyondLastLine: false,
|
||||
lineNumbers: "on",
|
||||
diffCodeLens: false,
|
||||
originalEditable: false,
|
||||
wordWrap: this.wordWrap,
|
||||
hideUnchangedRegions: { enabled: this.hideUnchanged },
|
||||
ignoreTrimWhitespace: false
|
||||
});
|
||||
|
||||
this.setModels(monaco);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to load Monaco diff editor", error);
|
||||
});
|
||||
},
|
||||
|
||||
updated() {
|
||||
this.host = this.el.querySelector(".monaco-diff-editor-instance");
|
||||
this.originalInput = this.el.querySelector(".monaco-diff-original");
|
||||
this.modifiedInput = this.el.querySelector(".monaco-diff-modified");
|
||||
this.applyDataset();
|
||||
|
||||
if (!this.editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadMonaco().then((monaco) => {
|
||||
ensureMonacoTheme(monaco);
|
||||
monaco.editor.setTheme("bds-theme");
|
||||
|
||||
this.editor.updateOptions({
|
||||
renderSideBySide: this.viewStyle === "side-by-side",
|
||||
wordWrap: this.wordWrap,
|
||||
hideUnchangedRegions: { enabled: this.hideUnchanged }
|
||||
});
|
||||
|
||||
if (this.lastFilePath !== this.filePath) {
|
||||
this.setModels(monaco);
|
||||
return;
|
||||
}
|
||||
|
||||
const values = this.readValues();
|
||||
|
||||
if (this.originalModel && this.originalModel.getLanguageId() !== this.language) {
|
||||
monaco.editor.setModelLanguage(this.originalModel, this.language);
|
||||
}
|
||||
|
||||
if (this.modifiedModel && this.modifiedModel.getLanguageId() !== this.language) {
|
||||
monaco.editor.setModelLanguage(this.modifiedModel, this.language);
|
||||
}
|
||||
|
||||
if (this.originalModel && this.originalModel.getValue() !== values.original) {
|
||||
this.originalModel.setValue(values.original);
|
||||
}
|
||||
|
||||
if (this.modifiedModel && this.modifiedModel.getValue() !== values.modified) {
|
||||
this.modifiedModel.setValue(values.modified);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.originalModel?.dispose();
|
||||
this.modifiedModel?.dispose();
|
||||
this.editor?.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user