mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-25 19:41:14 -08:00
feat(editor): Retrieve previous chat message on arrow-up (#8696)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
parent
a5e6f5928a
commit
246f8cfcc3
|
@ -1073,6 +1073,7 @@ export interface WorkflowsState {
|
|||
workflowExecutionData: IExecutionResponse | null;
|
||||
workflowExecutionPairedItemMappings: { [itemId: string]: Set<string> };
|
||||
workflowsById: IWorkflowsMap;
|
||||
chatMessages: string[];
|
||||
isInDebugMode?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
</div>
|
||||
<MessageTyping v-if="isLoading" ref="messageContainer" />
|
||||
</div>
|
||||
<div v-if="node" class="logs-wrapper" data-test-id="lm-chat-logs">
|
||||
<div v-if="node && messages.length" class="logs-wrapper" data-test-id="lm-chat-logs">
|
||||
<n8n-text class="logs-title" tag="p" size="large">{{
|
||||
$locale.baseText('chat.window.logs')
|
||||
}}</n8n-text>
|
||||
|
@ -149,8 +149,8 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
|
|||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import MessageTyping from '@n8n/chat/components/MessageTyping.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
||||
const RunDataAi = defineAsyncComponent(
|
||||
|
@ -183,8 +183,8 @@ export default defineComponent({
|
|||
},
|
||||
mixins: [workflowRun],
|
||||
setup(props, ctx) {
|
||||
const externalHooks = useExternalHooks();
|
||||
const router = useRouter();
|
||||
const externalHooks = useExternalHooks();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
|
@ -203,6 +203,7 @@ export default defineComponent({
|
|||
modalBus: createEventBus(),
|
||||
node: null as INodeUi | null,
|
||||
WORKFLOW_LM_CHAT_MODAL_KEY,
|
||||
previousMessageIndex: 0,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -216,6 +217,8 @@ export default defineComponent({
|
|||
this.setConnectedNode();
|
||||
this.messages = this.getChatMessages();
|
||||
this.setNode();
|
||||
|
||||
setTimeout(() => this.$refs.inputField?.focus(), 0);
|
||||
},
|
||||
methods: {
|
||||
displayExecution(executionId: string) {
|
||||
|
@ -235,6 +238,20 @@ export default defineComponent({
|
|||
inputField.focus();
|
||||
},
|
||||
updated(event: KeyboardEvent) {
|
||||
const pastMessages = this.workflowsStore.getPastChatMessages;
|
||||
if (
|
||||
(this.currentMessage.length === 0 || pastMessages.includes(this.currentMessage)) &&
|
||||
event.key === 'ArrowUp'
|
||||
) {
|
||||
const inputField = this.$refs.inputField as HTMLInputElement;
|
||||
|
||||
inputField?.blur();
|
||||
this.currentMessage =
|
||||
pastMessages[pastMessages.length - 1 - this.previousMessageIndex] ?? '';
|
||||
this.previousMessageIndex = (this.previousMessageIndex + 1) % pastMessages.length;
|
||||
// Refocus to move the cursor to the end of the input
|
||||
setTimeout(() => inputField?.focus(), 0);
|
||||
}
|
||||
if (event.key === 'Enter' && !event.shiftKey && this.currentMessage) {
|
||||
void this.sendChatMessage(this.currentMessage);
|
||||
event.stopPropagation();
|
||||
|
@ -255,6 +272,7 @@ export default defineComponent({
|
|||
} as ChatMessage);
|
||||
|
||||
this.currentMessage = '';
|
||||
this.previousMessageIndex = 0;
|
||||
await this.$nextTick();
|
||||
this.scrollToLatestMessage();
|
||||
await this.startWorkflowWithMessage(message);
|
||||
|
@ -272,7 +290,7 @@ export default defineComponent({
|
|||
}
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
const chatNode = this.workflowHelpers.getNodes().find((node: INodeUi): boolean => {
|
||||
const chatNode = this.workflowsStore.getNodes().find((node: INodeUi): boolean => {
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (!nodeType) return false;
|
||||
|
||||
|
@ -454,6 +472,7 @@ export default defineComponent({
|
|||
source: 'RunData.ManualChatMessage',
|
||||
});
|
||||
|
||||
this.workflowsStore.appendChatMessage(message);
|
||||
if (!response) {
|
||||
this.showError(
|
||||
new Error('It was not possible to start workflow!'),
|
||||
|
|
|
@ -140,7 +140,7 @@
|
|||
"chat.window.logs": "Log (for last message)",
|
||||
"chat.window.noChatNode": "No Chat Node",
|
||||
"chat.window.noExecution": "Nothing got executed yet",
|
||||
"chat.window.chat.placeholder": "Type in message",
|
||||
"chat.window.chat.placeholder": "Type a message, or press ‘up’ arrow for previous one",
|
||||
"chat.window.chat.sendButtonText": "Send",
|
||||
"chat.window.chat.provideMessage": "Please provide a message",
|
||||
"chat.window.chat.emptyChatMessage": "Empty chat message",
|
||||
|
|
|
@ -125,6 +125,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
|||
executionWaitingForWebhook: false,
|
||||
nodeMetadata: {},
|
||||
isInDebugMode: false,
|
||||
chatMessages: [],
|
||||
}),
|
||||
getters: {
|
||||
// Workflow getters
|
||||
|
@ -277,6 +278,9 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
|||
getTotalFinishedExecutionsCount(): number {
|
||||
return this.finishedExecutionsCount;
|
||||
},
|
||||
getPastChatMessages(): string[] {
|
||||
return Array.from(new Set(this.chatMessages));
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
getPinDataSize(pinData: Record<string, string | INodeExecutionData[]> = {}): number {
|
||||
|
@ -1436,5 +1440,13 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
|||
},
|
||||
};
|
||||
},
|
||||
|
||||
resetChatMessages(): void {
|
||||
this.chatMessages = [];
|
||||
},
|
||||
|
||||
appendChatMessage(message: string): void {
|
||||
this.chatMessages.push(message);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1013,6 +1013,7 @@ export default defineComponent({
|
|||
this.instance.unbind();
|
||||
this.instance.destroy();
|
||||
this.uiStore.stateIsDirty = false;
|
||||
this.workflowsStore.resetChatMessages();
|
||||
window.removeEventListener('message', this.onPostMessageReceived);
|
||||
nodeViewEventBus.off('newWorkflow', this.newWorkflow);
|
||||
nodeViewEventBus.off('importWorkflowData', this.onImportWorkflowDataEvent);
|
||||
|
|
Loading…
Reference in a new issue