From b3a6a7e4af8429a81aa6302028935cbf61702a57 Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Tue, 20 May 2025 03:11:18 +0600 Subject: [PATCH] wip --- src/components/ChatEditor/ChatEditor.tsx | 60 +++- .../VariableExtension/VariableSuggestion.tsx | 31 +-- .../RoadmapAIChat/RoadmapAIChat.css | 141 ++++++++++ .../RoadmapAIChat/RoadmapAIChat.tsx | 258 ++++++++++++++++-- 4 files changed, 451 insertions(+), 39 deletions(-) create mode 100644 src/components/RoadmapAIChat/RoadmapAIChat.css 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) => (