diff --git a/src/components/ChatEditor/ChatEditor.tsx b/src/components/ChatEditor/ChatEditor.tsx
index 9a8a368de..3fe5284f7 100644
--- a/src/components/ChatEditor/ChatEditor.tsx
+++ b/src/components/ChatEditor/ChatEditor.tsx
@@ -1,12 +1,21 @@
import './ChatEditor.css';
-import { EditorContent, useEditor } from '@tiptap/react';
+import {
+ Editor,
+ EditorContent,
+ useEditor,
+ type JSONContent,
+} from '@tiptap/react';
import DocumentExtension from '@tiptap/extension-document';
import ParagraphExtension from '@tiptap/extension-paragraph';
import TextExtension from '@tiptap/extension-text';
import Placeholder from '@tiptap/extension-placeholder';
import { VariableExtension } from './VariableExtension/VariableExtension';
import { variableSuggestion } from './VariableExtension/VariableSuggestion';
+import { queryClient } from '../../stores/query-client';
+import { roadmapTreeMappingOptions } from '../../queries/roadmap-tree';
+import { useQuery } from '@tanstack/react-query';
+import { useEffect, type RefObject } from 'react';
const extensions = [
DocumentExtension,
@@ -22,7 +31,20 @@ const extensions = [
const content = '
';
-export function ChatEditor() {
+type ChatEditorProps = {
+ editorRef: RefObject;
+ roadmapId: string;
+ onSubmit: (content: JSONContent) => void;
+};
+
+export function ChatEditor(props: ChatEditorProps) {
+ const { roadmapId, onSubmit, editorRef } = props;
+
+ const { data: roadmapTreeData } = useQuery(
+ roadmapTreeMappingOptions(roadmapId),
+ queryClient,
+ );
+
const editor = useEditor({
extensions,
content,
@@ -36,21 +58,53 @@ export function ChatEditor() {
}
if (event.key === 'Enter' && !event.shiftKey) {
+ // check if the variable suggestion list is focused
+ // if it is, return false so the default behavior is not triggered
+ const variableSuggestionList = document.getElementById(
+ 'variable-suggestion-list',
+ );
+ if (variableSuggestionList) {
+ return false;
+ }
+
event.preventDefault();
+ onSubmit(editor.getJSON());
return true;
}
if (event.key === 'Enter' && event.shiftKey) {
event.preventDefault();
- editor.commands.insertContent('');
+ editor.commands.insertContent([
+ { type: 'text', text: ' ' },
+ { type: 'paragraph' },
+ ]);
return true;
}
return false;
},
},
+ onUpdate: ({ editor }) => {
+ editorRef.current = editor;
+ },
+ onDestroy: () => {
+ editorRef.current = null;
+ },
});
+ useEffect(() => {
+ if (!editor || !roadmapTreeData) {
+ return;
+ }
+
+ editor.storage.variable.variables = roadmapTreeData.map((mapping) => {
+ return {
+ id: mapping._id,
+ label: mapping.text,
+ };
+ });
+ }, [editor, roadmapTreeData]);
+
return (
diff --git a/src/components/ChatEditor/VariableExtension/VariableSuggestion.tsx b/src/components/ChatEditor/VariableExtension/VariableSuggestion.tsx
index 6be201511..d49a8178b 100644
--- a/src/components/ChatEditor/VariableExtension/VariableSuggestion.tsx
+++ b/src/components/ChatEditor/VariableExtension/VariableSuggestion.tsx
@@ -25,34 +25,24 @@ export const VariableList = forwardRef((props: VariableListProps, ref) => {
command(item);
};
- const upHandler = () => {
- setSelectedIndex((selectedIndex + items.length - 1) % items.length);
- };
-
- const downHandler = () => {
- setSelectedIndex((selectedIndex + 1) % items.length);
- };
-
- const enterHandler = () => {
- selectItem(selectedIndex);
- };
-
- useEffect(() => setSelectedIndex(0), [items]);
+ useEffect(() => {
+ setSelectedIndex(0);
+ }, [items]);
useImperativeHandle(ref, () => ({
onKeyDown: ({ event }: { event: KeyboardEvent }) => {
if (event.key === 'ArrowUp') {
- upHandler();
+ setSelectedIndex((selectedIndex + items.length - 1) % items.length);
return true;
}
if (event.key === 'ArrowDown') {
- downHandler();
+ setSelectedIndex((selectedIndex + 1) % items.length);
return true;
}
if (event.key === 'Enter') {
- enterHandler();
+ selectItem(selectedIndex);
return true;
}
@@ -61,12 +51,15 @@ export const VariableList = forwardRef((props: VariableListProps, ref) => {
}));
return (
-
+
{items.length ? (
items.map((item, index) => (