From ed19f0f39b2a5d4daa67a0645bb82ce0e71968fb Mon Sep 17 00:00:00 2001 From: Suguru Inoue Date: Tue, 15 Apr 2025 13:26:02 +0200 Subject: [PATCH] feat(editor): Show logs panel in execution history page (#14477) --- .../chat/src/components/MessageTyping.vue | 1 - .../frontend/@n8n/chat/src/plugins/chat.ts | 5 - .../frontend/@n8n/chat/src/types/messages.ts | 1 - .../frontend/editor-ui/src/__tests__/mocks.ts | 13 ++ .../components/CanvasChat/CanvasChat.test.ts | 6 - .../src/components/CanvasChat/CanvasChat.vue | 4 +- .../components/ChatMessagesPanel.vue | 12 +- .../composables/useChatMessaging.ts | 69 +----- .../CanvasChat/composables/useChatState.ts | 17 +- .../CanvasChat/composables/useChatTrigger.ts | 7 +- .../CanvasChat/composables/usePiPWindow.ts | 6 +- .../CanvasChat/future/LogsPanel.test.ts | 1 + .../CanvasChat/future/LogsPanel.vue | 61 +++-- .../future/components/DemoFooter.vue | 14 ++ .../components/LogsOverviewPanel.test.ts | 28 ++- .../future/components/LogsOverviewPanel.vue | 29 +-- .../future/components/LogsOverviewRow.vue | 21 +- .../src/components/CanvasChat/types/logs.ts | 10 +- .../src/components/CanvasChat/utils.test.ts | 48 ++++ .../src/components/CanvasChat/utils.ts | 122 ++++++++++ .../src/components/RunDataAi/utils.test.ts | 219 ++++++++++++++++-- .../src/components/RunDataAi/utils.ts | 43 +++- .../WorkflowExecutionsInfoAccordion.vue | 6 +- .../src/composables/useRunWorkflow.ts | 8 +- packages/frontend/editor-ui/src/constants.ts | 3 + packages/frontend/editor-ui/src/router.ts | 3 + .../editor-ui/src/stores/workflows.store.ts | 4 +- 27 files changed, 596 insertions(+), 165 deletions(-) create mode 100644 packages/frontend/editor-ui/src/components/CanvasChat/future/components/DemoFooter.vue create mode 100644 packages/frontend/editor-ui/src/components/CanvasChat/utils.test.ts create mode 100644 packages/frontend/editor-ui/src/components/CanvasChat/utils.ts diff --git a/packages/frontend/@n8n/chat/src/components/MessageTyping.vue b/packages/frontend/@n8n/chat/src/components/MessageTyping.vue index e8dd3cf508..138fdcf268 100644 --- a/packages/frontend/@n8n/chat/src/components/MessageTyping.vue +++ b/packages/frontend/@n8n/chat/src/components/MessageTyping.vue @@ -18,7 +18,6 @@ const message: ChatMessage = { id: 'typing', text: '', sender: 'bot', - createdAt: '', }; const messageContainer = ref>(); const classes = computed(() => { diff --git a/packages/frontend/@n8n/chat/src/plugins/chat.ts b/packages/frontend/@n8n/chat/src/plugins/chat.ts index 31b1e6dd3c..1bdadb1f7e 100644 --- a/packages/frontend/@n8n/chat/src/plugins/chat.ts +++ b/packages/frontend/@n8n/chat/src/plugins/chat.ts @@ -21,7 +21,6 @@ export const ChatPlugin: Plugin = { id: uuidv4(), text, sender: 'bot', - createdAt: new Date().toISOString(), })), ); @@ -31,7 +30,6 @@ export const ChatPlugin: Plugin = { text, sender: 'user', files, - createdAt: new Date().toISOString(), }; messages.value.push(sentMessage); @@ -62,7 +60,6 @@ export const ChatPlugin: Plugin = { id: uuidv4(), text: textMessage, sender: 'bot', - createdAt: new Date().toISOString(), }; messages.value.push(receivedMessage); @@ -80,13 +77,11 @@ export const ChatPlugin: Plugin = { const sessionId = localStorage.getItem(localStorageSessionIdKey) ?? uuidv4(); const previousMessagesResponse = await api.loadPreviousSession(sessionId, options); - const timestamp = new Date().toISOString(); messages.value = (previousMessagesResponse?.data || []).map((message, index) => ({ id: `${index}`, text: message.kwargs.content, sender: message.id.includes('HumanMessage') ? 'user' : 'bot', - createdAt: timestamp, })); if (messages.value.length) { diff --git a/packages/frontend/@n8n/chat/src/types/messages.ts b/packages/frontend/@n8n/chat/src/types/messages.ts index 61433a2c53..2c7350279d 100644 --- a/packages/frontend/@n8n/chat/src/types/messages.ts +++ b/packages/frontend/@n8n/chat/src/types/messages.ts @@ -13,7 +13,6 @@ export interface ChatMessageText extends ChatMessageBase { interface ChatMessageBase { id: string; - createdAt: string; transparent?: boolean; sender: 'user' | 'bot'; files?: File[]; diff --git a/packages/frontend/editor-ui/src/__tests__/mocks.ts b/packages/frontend/editor-ui/src/__tests__/mocks.ts index 373c3fdc30..d2ce79969e 100644 --- a/packages/frontend/editor-ui/src/__tests__/mocks.ts +++ b/packages/frontend/editor-ui/src/__tests__/mocks.ts @@ -10,6 +10,7 @@ import type { LoadedClass, INodeTypeDescription, INodeIssues, + ITaskData, } from 'n8n-workflow'; import { NodeConnectionTypes, NodeHelpers, Workflow } from 'n8n-workflow'; import { v4 as uuid } from 'uuid'; @@ -203,3 +204,15 @@ export function createTestNode(node: Partial = {}): INode { ...node, }; } + +export function createTestTaskData(partialData: Partial): ITaskData { + return { + startTime: 0, + executionTime: 1, + executionIndex: 0, + source: [], + executionStatus: 'success', + data: { main: [[{ json: {} }]] }, + ...partialData, + }; +} diff --git a/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.test.ts b/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.test.ts index 3cac570e55..8b11376484 100644 --- a/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.test.ts +++ b/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.test.ts @@ -311,7 +311,6 @@ describe('CanvasChat', () => { id: '1', text: 'Existing message', sender: 'user', - createdAt: new Date().toISOString(), }, ]; @@ -321,7 +320,6 @@ describe('CanvasChat', () => { return { sendMessage: vi.fn(), - extractResponseMessage: vi.fn(), previousMessageIndex: ref(0), isLoading: computed(() => false), }; @@ -386,7 +384,6 @@ describe('CanvasChat', () => { beforeEach(() => { vi.spyOn(useChatMessaging, 'useChatMessaging').mockReturnValue({ sendMessage: vi.fn(), - extractResponseMessage: vi.fn(), previousMessageIndex: ref(0), isLoading: computed(() => false), }); @@ -472,13 +469,11 @@ describe('CanvasChat', () => { id: '1', text: 'Original message', sender: 'user', - createdAt: new Date().toISOString(), }, { id: '2', text: 'AI response', sender: 'bot', - createdAt: new Date().toISOString(), }, ]; vi.spyOn(useChatMessaging, 'useChatMessaging').mockImplementation(({ messages }) => { @@ -486,7 +481,6 @@ describe('CanvasChat', () => { return { sendMessage: sendMessageSpy, - extractResponseMessage: vi.fn(), previousMessageIndex: ref(0), isLoading: computed(() => false), }; diff --git a/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.vue b/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.vue index 0218a07068..a770657369 100644 --- a/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.vue +++ b/packages/frontend/editor-ui/src/components/CanvasChat/CanvasChat.vue @@ -21,7 +21,6 @@ const workflowsStore = useWorkflowsStore(); const canvasStore = useCanvasStore(); // Component state -const isDisabled = ref(false); const container = ref(); const pipContainer = useTemplateRef('pipContainer'); const pipContent = useTemplateRef('pipContent'); @@ -69,13 +68,12 @@ const { sendMessage, refreshSession, displayExecution, -} = useChatState(isDisabled, onWindowResize); +} = useChatState(false, onWindowResize); // Expose internal state for testing defineExpose({ messages, currentSessionId, - isDisabled, workflow, }); diff --git a/packages/frontend/editor-ui/src/components/CanvasChat/components/ChatMessagesPanel.vue b/packages/frontend/editor-ui/src/components/CanvasChat/components/ChatMessagesPanel.vue index b34ce103d5..71507dc5eb 100644 --- a/packages/frontend/editor-ui/src/components/CanvasChat/components/ChatMessagesPanel.vue +++ b/packages/frontend/editor-ui/src/components/CanvasChat/components/ChatMessagesPanel.vue @@ -19,11 +19,13 @@ interface Props { sessionId: string; showCloseButton?: boolean; isOpen?: boolean; + isReadOnly?: boolean; isNewLogsEnabled?: boolean; } const props = withDefaults(defineProps(), { isOpen: true, + isReadOnly: false, isNewLogsEnabled: false, }); @@ -145,7 +147,7 @@ async function copySessionId() { @click="emit('clickHeader')" >