upgraded ui

This commit is contained in:
Saifeddine ALOUI 2024-12-20 21:56:00 +01:00
parent b930b7940e
commit 54e09e85da
9 changed files with 4723 additions and 4268 deletions

3997
web/dist/assets/index-Bt6VF9H5.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

8
web/dist/assets/index-COFFlPfA.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
web/dist/index.html vendored
View File

@ -6,8 +6,8 @@
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script> <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LoLLMS WebUI</title> <title>LoLLMS WebUI</title>
<script type="module" crossorigin src="/assets/index-DQmEh9rd.js"></script> <script type="module" crossorigin src="/assets/index-Bt6VF9H5.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C5n6m1nm.css"> <link rel="stylesheet" crossorigin href="/assets/index-COFFlPfA.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

636
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,15 +16,17 @@
"axios": "^1.7.4", "axios": "^1.7.4",
"baklavajs": "^2.3.0", "baklavajs": "^2.3.0",
"dompurify": "^3.1.3", "dompurify": "^3.1.3",
"feather-icons": "^4.29.0", "feather-icons": "^4.29.2",
"flowbite": "^1.6.5", "flowbite": "^1.6.5",
"flowbite-vue": "^0.0.10", "flowbite-vue": "^0.0.7",
"highlight.js": "^11.8.0", "highlight.js": "^11.11.0",
"katex": "^0.16.18",
"markdown-it": "^13.0.2", "markdown-it": "^13.0.2",
"markdown-it-anchor": "^8.6.7", "markdown-it-anchor": "^8.6.7",
"markdown-it-attrs": "^4.1.6", "markdown-it-attrs": "^4.1.6",
"markdown-it-emoji": "^2.0.2", "markdown-it-emoji": "^2.0.2",
"markdown-it-implicit-figures": "^0.11.0", "markdown-it-implicit-figures": "^0.11.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-math": "^4.1.1", "markdown-it-math": "^4.1.1",
"markdown-it-mathjax": "^2.0.0", "markdown-it-mathjax": "^2.0.0",
"markdown-it-multimd-table": "^4.2.3", "markdown-it-multimd-table": "^4.2.3",
@ -33,12 +35,15 @@
"mathjax": "^3.2.2", "mathjax": "^3.2.2",
"mermaid": "^11.2.1", "mermaid": "^11.2.1",
"monaco-editor": "^0.51.0", "monaco-editor": "^0.51.0",
"monaco-editor-vue3": "^0.1.10",
"papaparse": "^5.4.1", "papaparse": "^5.4.1",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"socket.io-client": "^4.6.1", "socket.io-client": "^4.6.1",
"three": "^0.159.0", "three": "^0.159.0",
"vue": "^3.5.10", "vue": "^3.5.10",
"vue-inline-svg": "^2.1.3", "vue-inline-svg": "^2.1.3",
"vue-json-pretty": "^2.4.0",
"vue-markdown": "^2.1.3",
"vue-router": "^4.1.6", "vue-router": "^4.1.6",
"vuex": "^4.0.2" "vuex": "^4.0.2"
}, },

View File

@ -1,175 +1,177 @@
<template> <template>
<div class="break-all container w-full"> <div class="break-all container w-full">
<div ref="mdRender" class="markdown-content"> <div ref="mdRender" class="markdown-content">
<div v-for="(item, index) in markdownItems" :key="index"> <div v-for="(item, index) in markdownItems" :key="index">
<code-block <code-block
v-if="item.type === 'code'" v-if="item.type === 'code'"
:host="host" :host="host"
:language="item.language" :language="item.language"
:code="item.code" :code="item.code"
:discussion_id="discussion_id" :discussion_id="discussion_id"
:message_id="message_id" :message_id="message_id"
:client_id="client_id" :client_id="client_id"
@update-code="updateCode(index, $event)" @update-code="updateCode(index, $event)"
></code-block> ></code-block>
<div v-else v-html="item.html"></div> <div v-else v-html="item.html"></div>
</div>
</div> </div>
</div> </div>
</div> </template>
</template>
<script>
<script> import { nextTick, ref, onMounted, watch } from 'vue';
import { nextTick, ref, onMounted, watch } from 'vue'; import feather from 'feather-icons';
import feather from 'feather-icons'; import MarkdownIt from 'markdown-it'
import MarkdownIt from 'markdown-it'; import markdownItKatex from 'markdown-it-katex'
import emoji from 'markdown-it-emoji'; import emoji from 'markdown-it-emoji';
import anchor from 'markdown-it-anchor'; import anchor from 'markdown-it-anchor';
import MarkdownItMultimdTable from 'markdown-it-multimd-table'; import MarkdownItMultimdTable from 'markdown-it-multimd-table';
import implicitFigures from 'markdown-it-implicit-figures'; import implicitFigures from 'markdown-it-implicit-figures';
import 'highlight.js/styles/tomorrow-night-blue.css'; import 'highlight.js/styles/tomorrow-night-blue.css';
import 'highlight.js/styles/tokyo-night-dark.css'; import 'highlight.js/styles/tokyo-night-dark.css';
import attrs from 'markdown-it-attrs'; import attrs from 'markdown-it-attrs';
import CodeBlock from './CodeBlock.vue'; import CodeBlock from './CodeBlock.vue';
import hljs from 'highlight.js'; import hljs from 'highlight.js';
import mathjax from 'markdown-it-mathjax'; import mathjax from 'markdown-it-mathjax';
function escapeHtml(unsafe) { function escapeHtml(unsafe) {
return unsafe return unsafe
.replace(/&/g, "&amp;") .replace(/&/g, "&amp;")
.replace(/</g, "&lt;") .replace(/</g, "&lt;")
.replace(/>/g, "&gt;") .replace(/>/g, "&gt;")
.replace(/"/g, "&quot;") .replace(/"/g, "&quot;")
.replace(/'/g, "&#039;"); .replace(/'/g, "&#039;");
} }
export default { export default {
name: 'MarkdownRenderer', name: 'MarkdownRenderer',
props: { props: {
host: { host: {
type: String, type: String,
required: false, required: false,
default: "http://localhost:9600", default: "http://localhost:9600",
},
client_id: {
type: String,
required: true,
},
markdownText: {
type: String,
required: true,
},
discussion_id: {
type: [String, Number],
default: "0",
required: false,
},
message_id: {
value: "0",
type: [String, Number],
required: false,
},
},
components: {
CodeBlock,
},
setup(props) {
const md = new MarkdownIt({
html: true,
breaks: true, // Enable single line breaks
highlight: (code, language) => {
const validLanguage = language && hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(validLanguage, code).value;
}, },
renderInline: false, client_id: {
}) type: String,
.use(emoji) required: true,
.use(anchor) },
.use(implicitFigures, { markdownText: {
figcaption: true, type: String,
required: true,
},
discussion_id: {
type: [String, Number],
default: "0",
required: false,
},
message_id: {
value: "0",
type: [String, Number],
required: false,
},
},
components: {
CodeBlock,
},
setup(props) {
const md = new MarkdownIt({
html: true,
breaks: true, // Enable single line breaks
highlight: (code, language) => {
const validLanguage = language && hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(validLanguage, code).value;
},
renderInline: false,
}) })
.use(attrs) .use(emoji)
.use(MarkdownItMultimdTable, { .use(anchor)
enableRowspan: true, .use(implicitFigures, {
enableColspan: true, figcaption: true,
enableGridTables: true, })
enableGridTablesExtra: true, .use(attrs)
enableTableIndentation: true, .use(MarkdownItMultimdTable, {
tableCellPadding: ' ', enableRowspan: true,
tableCellJoiner: '|', enableColspan: true,
multilineCellStartMarker: '|>', enableGridTables: true,
multilineCellEndMarker: '<|', enableGridTablesExtra: true,
multilineCellPadding: ' ', enableTableIndentation: true,
multilineCellJoiner: '\n', tableCellPadding: ' ',
}) tableCellJoiner: '|',
.use(mathjax); // Ensure mathjax is used for inline LaTeX multilineCellStartMarker: '|>',
multilineCellEndMarker: '<|',
const markdownItems = ref([]); multilineCellPadding: ' ',
const updateMarkdown = () => { multilineCellJoiner: '\n',
if (props.markdownText) { })
let tokens = md.parse(props.markdownText, {}); .use(markdownItKatex)
let cumulated = [];
markdownItems.value = []; const markdownItems = ref([]);
for (let i = 0; i < tokens.length; i++) { const updateMarkdown = () => {
if (tokens[i].type !== 'fence') { if (props.markdownText) {
cumulated.push(tokens[i]); let tokens = md.parse(props.markdownText, {});
} else { let cumulated = [];
if (cumulated.length > 0) { markdownItems.value = [];
for (let i = 0; i < tokens.length; i++) {
if (tokens[i].type !== 'fence') {
cumulated.push(tokens[i]);
} else {
if (cumulated.length > 0) {
markdownItems.value.push({
type: 'html',
html: md.renderer.render(cumulated, md.options, {}),
});
cumulated = [];
}
markdownItems.value.push({ markdownItems.value.push({
type: 'html', type: 'code',
html: md.renderer.render(cumulated, md.options, {}), language: escapeHtml(tokens[i].info),
code: tokens[i].content,
}); });
cumulated = [];
} }
markdownItems.value.push({
type: 'code',
language: escapeHtml(tokens[i].info),
code: tokens[i].content,
});
} }
if (cumulated.length > 0) {
markdownItems.value.push({
type: 'html',
html: md.renderer.render(cumulated, md.options, {}),
});
cumulated = [];
}
} else {
markdownItems.value = [];
} }
if (cumulated.length > 0) { nextTick(() => {
markdownItems.value.push({ feather.replace();
type: 'html', if (window.MathJax) {
html: md.renderer.render(cumulated, md.options, {}), window.MathJax.typesetPromise(); // Ensure MathJax typesets after rendering
}); }
cumulated = []; });
} };
} else {
markdownItems.value = []; const updateCode = (index, newCode) => {
} markdownItems.value[index].code = newCode;
nextTick(() => { };
feather.replace();
if (window.MathJax) { watch(() => props.markdownText, updateMarkdown);
window.MathJax.typesetPromise(); // Ensure MathJax typesets after rendering onMounted(() => {
} updateMarkdown();
}); });
}; return { markdownItems, updateCode };
},
const updateCode = (index, newCode) => { };
markdownItems.value[index].code = newCode; </script>
};
<style>
watch(() => props.markdownText, updateMarkdown); /* Your existing styles */
onMounted(() => { .katex-display {
updateMarkdown(); display: inline-block;
}); margin: 0;
return { markdownItems, updateCode }; }
},
}; .katex {
</script> display: inline-block;
white-space: nowrap;
<style> }
/* Your existing styles */ .inline-latex {
.katex-display { display: inline !important;
display: inline-block; }
margin: 0; </style>
}
.katex {
display: inline-block;
white-space: nowrap;
}
.inline-latex {
display: inline !important;
}
</style>

View File

@ -2,6 +2,7 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv } from 'vite' import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import monacoEditorPlugin from 'vite-plugin-monaco-editor'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
@ -14,6 +15,9 @@ export default async ({ mode }) => {
plugins: [ plugins: [
vue() vue()
], ],
optimizeDeps: {
include: ['monaco-editor/esm/vs/editor/editor.main.js']
},
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))