feat: version 2.9.1 -- resaltado de sintaxis en bloques de codigo de documentos .md

Los bloques de codigo dentro de un .md visto en Documentos ahora tienen colores de token
(highlight.js + marked-highlight), con el tema "Visual Studio" claro/oscuro para que se vea
parecido a VSCode y se adapte solo al tema de la app. Se usa highlight.js/lib/core y solo se
registran los lenguajes esperados en este proyecto (js/ts, bash, json, python, sql, yaml,
html/xml, css, ini, dockerfile, markdown) para no inflar el bundle con el paquete completo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-07 17:38:46 -05:00
parent 3d220bcc20
commit dd8384fc88
7 changed files with 89 additions and 8 deletions
+10 -3
View File
@@ -6,11 +6,15 @@ import { listAttachments, uploadAttachment, deleteAttachment, downloadAttachment
import { renderMarkdown } from '../utils/renderMarkdown.js';
import { Button } from './Button.jsx';
import { DetailPopup } from './DetailPopup.jsx';
// Tema de colores de bloques de codigo al estilo Visual Studio/VSCode (claro y oscuro),
// inyectado solo mientras se ve un .md -- ?inline evita que Vite lo aplique global siempre.
import hljsLight from 'highlight.js/styles/vs.css?inline';
import hljsDark from 'highlight.js/styles/vs2015.css?inline';
const VIEWABLE_MIME = new Set(['text/plain', 'text/markdown']);
export function AttachmentsPanel({ entityType, entityId }) {
const { t, openDialog } = useUi();
const { t, openDialog, theme } = useUi();
const runAction = useAction();
const { data: files, reload } = useAsync(() => listAttachments(entityType, entityId), [entityType, entityId]);
const inputRef = useRef(null);
@@ -83,8 +87,11 @@ export function AttachmentsPanel({ entityType, entityId }) {
{viewLoading ? (
<div className="text-muted">{t('common_loading')}</div>
) : viewing?.mime_type === 'text/markdown' ? (
// eslint-disable-next-line react/no-danger -- sanitizado con DOMPurify en renderMarkdown()
<div className="markdown-view" dangerouslySetInnerHTML={{ __html: renderMarkdown(viewContent) }} />
<>
<style>{theme === 'light' ? hljsLight : hljsDark}</style>
{/* eslint-disable-next-line react/no-danger -- sanitizado con DOMPurify en renderMarkdown() */}
<div className="markdown-view" dangerouslySetInnerHTML={{ __html: renderMarkdown(viewContent) }} />
</>
) : (
<pre className="text-view">{viewContent}</pre>
)}
+46
View File
@@ -1,5 +1,51 @@
import { marked } from 'marked';
import { markedHighlight } from 'marked-highlight';
import hljs from 'highlight.js/lib/core';
import DOMPurify from 'dompurify';
import javascript from 'highlight.js/lib/languages/javascript';
import typescript from 'highlight.js/lib/languages/typescript';
import xml from 'highlight.js/lib/languages/xml';
import css from 'highlight.js/lib/languages/css';
import json from 'highlight.js/lib/languages/json';
import bash from 'highlight.js/lib/languages/bash';
import python from 'highlight.js/lib/languages/python';
import sql from 'highlight.js/lib/languages/sql';
import yaml from 'highlight.js/lib/languages/yaml';
import markdown from 'highlight.js/lib/languages/markdown';
import ini from 'highlight.js/lib/languages/ini';
import dockerfile from 'highlight.js/lib/languages/dockerfile';
// Solo los lenguajes que realmente se esperan en documentos de este proyecto -- se usa
// highlight.js/lib/core (sin lenguajes) en vez del paquete completo (~1MB) para no inflar el
// bundle con lenguajes que nunca se van a usar aqui.
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('js', javascript);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('ts', typescript);
hljs.registerLanguage('xml', xml);
hljs.registerLanguage('html', xml);
hljs.registerLanguage('css', css);
hljs.registerLanguage('json', json);
hljs.registerLanguage('bash', bash);
hljs.registerLanguage('sh', bash);
hljs.registerLanguage('shell', bash);
hljs.registerLanguage('python', python);
hljs.registerLanguage('py', python);
hljs.registerLanguage('sql', sql);
hljs.registerLanguage('yaml', yaml);
hljs.registerLanguage('yml', yaml);
hljs.registerLanguage('markdown', markdown);
hljs.registerLanguage('md', markdown);
hljs.registerLanguage('ini', ini);
hljs.registerLanguage('dockerfile', dockerfile);
marked.use(markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
},
}));
// Un documento .md subido por cualquier miembro del proyecto puede ser visto por otros
// miembros -- sin sanitizar, HTML/JS embebido en el markdown se ejecutaria al renderizarlo