mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
feat(editor): Logs markdown block improvements (#10681)
This commit is contained in:
parent
54ab2b14e4
commit
db6e8326c7
|
@ -36,7 +36,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vueuse/core": "^10.11.0",
|
"@vueuse/core": "^10.11.0",
|
||||||
"highlight.js": "^11.8.0",
|
"highlight.js": "catalog:frontend",
|
||||||
"markdown-it-link-attributes": "^4.0.1",
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
"uuid": "catalog:",
|
"uuid": "catalog:",
|
||||||
"vue": "catalog:frontend",
|
"vue": "catalog:frontend",
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
"fast-json-stable-stringify": "^2.1.0",
|
"fast-json-stable-stringify": "^2.1.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"flatted": "^3.2.4",
|
"flatted": "^3.2.4",
|
||||||
|
"highlight.js": "catalog:frontend",
|
||||||
"humanize-duration": "^3.27.2",
|
"humanize-duration": "^3.27.2",
|
||||||
"jsonpath": "^1.1.1",
|
"jsonpath": "^1.1.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { ref, onMounted } from 'vue';
|
||||||
import type { ParsedAiContent } from './useAiContentParsers';
|
import type { ParsedAiContent } from './useAiContentParsers';
|
||||||
import { useAiContentParsers } from './useAiContentParsers';
|
import { useAiContentParsers } from './useAiContentParsers';
|
||||||
import VueMarkdown from 'vue-markdown-render';
|
import VueMarkdown from 'vue-markdown-render';
|
||||||
|
import hljs from 'highlight.js/lib/core';
|
||||||
import { useClipboard } from '@/composables/useClipboard';
|
import { useClipboard } from '@/composables/useClipboard';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
|
@ -38,6 +39,27 @@ function getInitialExpandedState() {
|
||||||
return !collapsedTypes[props.runData.inOut].includes(props.runData.type);
|
return !collapsedTypes[props.runData.inOut].includes(props.runData.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isJsonString(text: string) {
|
||||||
|
try {
|
||||||
|
JSON.parse(text);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const markdownOptions = {
|
||||||
|
highlight(str: string, lang: string) {
|
||||||
|
if (lang && hljs.getLanguage(lang)) {
|
||||||
|
try {
|
||||||
|
return hljs.highlight(str, { language: lang }).value;
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''; // use external default escaping
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
function parseAiRunData(run: IAiDataContent) {
|
function parseAiRunData(run: IAiDataContent) {
|
||||||
if (!run.data) {
|
if (!run.data) {
|
||||||
return;
|
return;
|
||||||
|
@ -75,7 +97,13 @@ function jsonToMarkdown(data: JsonMarkdown): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
return formatToJsonMarkdown(data);
|
// If data is a valid JSON string – format it as JSON markdown
|
||||||
|
if (isJsonString(data)) {
|
||||||
|
return formatToJsonMarkdown(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return original string otherwise
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatToJsonMarkdown(JSON.stringify(data, null, 2));
|
return formatToJsonMarkdown(JSON.stringify(data, null, 2));
|
||||||
|
@ -145,10 +173,15 @@ onMounted(() => {
|
||||||
<VueMarkdown
|
<VueMarkdown
|
||||||
:source="jsonToMarkdown(parsedContent.data as JsonMarkdown)"
|
:source="jsonToMarkdown(parsedContent.data as JsonMarkdown)"
|
||||||
:class="$style.markdown"
|
:class="$style.markdown"
|
||||||
|
:options="markdownOptions"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="parsedContent.type === 'markdown'">
|
<template v-if="parsedContent.type === 'markdown'">
|
||||||
<VueMarkdown :source="parsedContent.data" :class="$style.markdown" />
|
<VueMarkdown
|
||||||
|
:source="parsedContent.data"
|
||||||
|
:class="$style.markdown"
|
||||||
|
:options="markdownOptions"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<p
|
<p
|
||||||
v-if="parsedContent.type === 'text'"
|
v-if="parsedContent.type === 'text'"
|
||||||
|
@ -204,7 +237,7 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background-color: var(--color-foreground-light);
|
background: var(--chat--message--pre--background);
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
line-height: var(--font-line-height-xloose);
|
line-height: var(--font-line-height-xloose);
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-s);
|
||||||
|
|
|
@ -47,10 +47,12 @@ const outputTypeParsers: {
|
||||||
parsed: true,
|
parsed: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the memory parser if the response is a memory-like(chat) object
|
// Use the memory parser if the response is a memory-like(chat) object
|
||||||
if (response.messages && Array.isArray(response.messages)) {
|
if (response.messages && Array.isArray(response.messages)) {
|
||||||
return outputTypeParsers[NodeConnectionType.AiMemory](execData);
|
return outputTypeParsers[NodeConnectionType.AiMemory](execData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.generations) {
|
if (response.generations) {
|
||||||
const generations = response.generations as LmGeneration[];
|
const generations = response.generations as LmGeneration[];
|
||||||
|
|
||||||
|
@ -220,8 +222,8 @@ export const useAiContentParsers = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentJson = executionData.map((node) => {
|
const contentJson = executionData.map((node) => {
|
||||||
const hasBinarData = !isObjectEmpty(node.binary);
|
const hasBinaryData = !isObjectEmpty(node.binary);
|
||||||
return hasBinarData ? node.binary : node.json;
|
return hasBinaryData ? node.binary : node.json;
|
||||||
});
|
});
|
||||||
|
|
||||||
const parser = outputTypeParsers[endpointType as AllowedEndpointType];
|
const parser = outputTypeParsers[endpointType as AllowedEndpointType];
|
||||||
|
|
|
@ -58,6 +58,9 @@ catalogs:
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^1.6.0
|
specifier: ^1.6.0
|
||||||
version: 1.6.0
|
version: 1.6.0
|
||||||
|
highlight.js:
|
||||||
|
specifier: ^11.8.0
|
||||||
|
version: 11.9.0
|
||||||
vite:
|
vite:
|
||||||
specifier: ^5.2.12
|
specifier: ^5.2.12
|
||||||
version: 5.2.12
|
version: 5.2.12
|
||||||
|
@ -255,7 +258,7 @@ importers:
|
||||||
specifier: ^10.11.0
|
specifier: ^10.11.0
|
||||||
version: 10.11.0(vue@3.4.21(typescript@5.5.2))
|
version: 10.11.0(vue@3.4.21(typescript@5.5.2))
|
||||||
highlight.js:
|
highlight.js:
|
||||||
specifier: ^11.8.0
|
specifier: catalog:frontend
|
||||||
version: 11.9.0
|
version: 11.9.0
|
||||||
markdown-it-link-attributes:
|
markdown-it-link-attributes:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
|
@ -1340,6 +1343,9 @@ importers:
|
||||||
flatted:
|
flatted:
|
||||||
specifier: ^3.2.4
|
specifier: ^3.2.4
|
||||||
version: 3.2.7
|
version: 3.2.7
|
||||||
|
highlight.js:
|
||||||
|
specifier: catalog:frontend
|
||||||
|
version: 11.9.0
|
||||||
humanize-duration:
|
humanize-duration:
|
||||||
specifier: ^3.27.2
|
specifier: ^3.27.2
|
||||||
version: 3.27.3
|
version: 3.27.3
|
||||||
|
@ -13139,8 +13145,8 @@ packages:
|
||||||
vue-component-type-helpers@2.0.19:
|
vue-component-type-helpers@2.0.19:
|
||||||
resolution: {integrity: sha512-cN3f1aTxxKo4lzNeQAkVopswuImUrb5Iurll9Gaw5cqpnbTAxtEMM1mgi6ou4X79OCyqYv1U1mzBHJkzmiK82w==}
|
resolution: {integrity: sha512-cN3f1aTxxKo4lzNeQAkVopswuImUrb5Iurll9Gaw5cqpnbTAxtEMM1mgi6ou4X79OCyqYv1U1mzBHJkzmiK82w==}
|
||||||
|
|
||||||
vue-component-type-helpers@2.1.4:
|
vue-component-type-helpers@2.1.6:
|
||||||
resolution: {integrity: sha512-aVqB3KxwpM76cYRkpnezl1J62E/1omzHQfx1yuz7zcbxmzmP/PeSgI20NEmkdeGnjZPVzm0V9fB4ZyRu5BBj4A==}
|
resolution: {integrity: sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==}
|
||||||
|
|
||||||
vue-demi@0.14.5:
|
vue-demi@0.14.5:
|
||||||
resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
|
resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
|
||||||
|
@ -18571,7 +18577,7 @@ snapshots:
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
vue: 3.4.21(typescript@5.5.2)
|
vue: 3.4.21(typescript@5.5.2)
|
||||||
vue-component-type-helpers: 2.1.4
|
vue-component-type-helpers: 2.1.6
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
- prettier
|
- prettier
|
||||||
|
@ -28055,7 +28061,7 @@ snapshots:
|
||||||
|
|
||||||
vue-component-type-helpers@2.0.19: {}
|
vue-component-type-helpers@2.0.19: {}
|
||||||
|
|
||||||
vue-component-type-helpers@2.1.4: {}
|
vue-component-type-helpers@2.1.6: {}
|
||||||
|
|
||||||
vue-demi@0.14.5(vue@3.4.21(typescript@5.5.2)):
|
vue-demi@0.14.5(vue@3.4.21(typescript@5.5.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -31,3 +31,4 @@ catalogs:
|
||||||
vue: ^3.4.21
|
vue: ^3.4.21
|
||||||
vue-tsc: ^2.0.19
|
vue-tsc: ^2.0.19
|
||||||
vue-markdown-render: ^2.2.1
|
vue-markdown-render: ^2.2.1
|
||||||
|
highlight.js: ^11.8.0
|
||||||
|
|
Loading…
Reference in a new issue