From c04a9b05950b6c157774751df64f533a33da1ef2 Mon Sep 17 00:00:00 2001 From: Nawaz Gafar Date: Fri, 8 Nov 2024 12:30:26 -0500 Subject: [PATCH 01/65] printing var manager for debugging purposes --- mito-ai/Untitled13.ipynb | 45 +++++++++++++++++++ .../src/Extensions/AiChat/ChatTaskpane.tsx | 5 +++ 2 files changed, 50 insertions(+) create mode 100644 mito-ai/Untitled13.ipynb diff --git a/mito-ai/Untitled13.ipynb b/mito-ai/Untitled13.ipynb new file mode 100644 index 000000000..0cd1c81fa --- /dev/null +++ b/mito-ai/Untitled13.ipynb @@ -0,0 +1,45 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "id": "7b3663a7-6e64-418c-bed7-9ed6b59fa7e4", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "data = {'numbers': [1], 'loan_amount': [1000], 'interest_rate': [0.05]}\n", + "simple_df = pd.DataFrame(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "acd81404-5fc4-4e22-ad21-f283f343accf", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx index 9ded544d9..a8be8ff2e 100644 --- a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx @@ -343,8 +343,13 @@ const ChatTaskpane: React.FC = ({ const lastAIMessagesIndex = chatHistoryManager.getLastAIMessageIndex() + function getVariableManager() { + console.log('variableManager', variableManager) + } + return (
+
} From da3d8178274bfc65c029dc51174ac00f1d888dc2 Mon Sep 17 00:00:00 2001 From: Nawaz Gafar Date: Fri, 8 Nov 2024 13:07:53 -0500 Subject: [PATCH 02/65] Added variable manager btn --- mito-ai/Untitled13.ipynb | 2 +- .../AiChat/ChatMessage/ChatInput.tsx | 19 ++++++++++++++++++- .../src/Extensions/AiChat/ChatTaskpane.tsx | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mito-ai/Untitled13.ipynb b/mito-ai/Untitled13.ipynb index 0cd1c81fa..5f320d68d 100644 --- a/mito-ai/Untitled13.ipynb +++ b/mito-ai/Untitled13.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "7b3663a7-6e64-418c-bed7-9ed6b59fa7e4", "metadata": {}, "outputs": [], diff --git a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx index cfa15a518..523811408 100644 --- a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx @@ -1,5 +1,6 @@ import React, { useEffect } from 'react'; import { classNames } from '../../../utils/classNames'; +import { IVariableManager } from '../../VariableManager/VariableManagerPlugin'; interface ChatInputProps { initialContent: string; @@ -7,6 +8,7 @@ interface ChatInputProps { onSave: (content: string) => void; onCancel?: () => void ; isEditing: boolean; + variableManager?: IVariableManager; } const ChatInput: React.FC = ({ @@ -14,7 +16,8 @@ const ChatInput: React.FC = ({ placeholder, onSave, onCancel, - isEditing + isEditing, + variableManager }) => { const [input, setInput] = React.useState(initialContent); const textAreaRef = React.useRef(null); @@ -33,6 +36,15 @@ const ChatInput: React.FC = ({ textarea.style.height = `${minHeight}px`; }; + const handleVariableManagerClick = () => { + console.log('variableManager', variableManager) + variableManager?.variables.map((variable) => { + console.log('name', variable.variable_name) + console.log('type', variable.type) + console.log('value', variable.value) + }) + } + useEffect(() => { adjustHeight(); }, [textAreaRef?.current?.value]); @@ -68,6 +80,11 @@ const ChatInput: React.FC = ({
} + {variableManager && + + } ) }; diff --git a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx index a8be8ff2e..168993944 100644 --- a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx @@ -397,6 +397,7 @@ const ChatTaskpane: React.FC = ({ onSave={sendChatInputMessage} onCancel={undefined} isEditing={false} + variableManager={variableManager} />
); From c9f1cec678de4fff83d52c086ab90e980f5b189d Mon Sep 17 00:00:00 2001 From: Nawaz Gafar Date: Fri, 8 Nov 2024 13:08:20 -0500 Subject: [PATCH 03/65] Cleanup --- mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx index 168993944..1eb842811 100644 --- a/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatTaskpane.tsx @@ -343,13 +343,8 @@ const ChatTaskpane: React.FC = ({ const lastAIMessagesIndex = chatHistoryManager.getLastAIMessageIndex() - function getVariableManager() { - console.log('variableManager', variableManager) - } - return (
-
} From 5e0c06b050f15e6263f3eded5199c4662559f801 Mon Sep 17 00:00:00 2001 From: Nawaz Gafar Date: Mon, 11 Nov 2024 12:10:26 -0500 Subject: [PATCH 04/65] Added helper functions for dropdown --- .../AiChat/ChatMessage/ChatInput.tsx | 87 +++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx index 523811408..43edd64dc 100644 --- a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useState, useEffect } from 'react'; import { classNames } from '../../../utils/classNames'; import { IVariableManager } from '../../VariableManager/VariableManagerPlugin'; @@ -6,9 +6,9 @@ interface ChatInputProps { initialContent: string; placeholder: string; onSave: (content: string) => void; - onCancel?: () => void ; + onCancel?: () => void; isEditing: boolean; - variableManager?: IVariableManager; + variableManager: IVariableManager; } const ChatInput: React.FC = ({ @@ -20,6 +20,9 @@ const ChatInput: React.FC = ({ variableManager }) => { const [input, setInput] = React.useState(initialContent); + const [isDropdownVisible, setDropdownVisible] = useState(false); + const [filteredOptions, setFilteredOptions] = useState([]); + const [selectedIndex, setSelectedIndex] = useState(0); const textAreaRef = React.useRef(null); // TextAreas cannot automatically adjust their height based on the content that they contain, @@ -45,6 +48,80 @@ const ChatInput: React.FC = ({ }) } + const handleInputChange = (event: React.ChangeEvent) => { + const value = event.target.value; + setInput(value); + + const cursorPosition = event.target.selectionStart; + const textBeforeCursor = value.slice(0, cursorPosition); + const words = textBeforeCursor.split(/\s+/); + const currentWord = words[words.length - 1]; + + if (currentWord.startsWith("@")) { + const query = currentWord.slice(1); + const filtered = variableManager?.variables.filter((variable) => variable.variable_name.startsWith(query)); + setFilteredOptions(filtered?.map(v => v.variable_name) || []); + setDropdownVisible(filtered?.length > 0 || false); + setSelectedIndex(0); + } else { + setDropdownVisible(false); + } + }; + + const handleOptionSelect = (username: string) => { + const textarea = document.querySelector('textarea'); + if (!textarea) return; + + const cursorPosition = textarea.selectionStart; + const textBeforeCursor = input.slice(0, cursorPosition); + const atIndex = textBeforeCursor.lastIndexOf("@"); + const textAfterAt = input.slice(atIndex); + const endOfWord = textAfterAt.search(/[\s\n]|$/); + + const newValue = + input.slice(0, atIndex) + + `@${username}` + + input.slice(atIndex + endOfWord); + + setInput(newValue); + setDropdownVisible(false); + + setTimeout(() => { + if (textarea) { + const newCursorPosition = atIndex + username.length + 1; + textarea.focus(); + textarea.setSelectionRange(newCursorPosition, newCursorPosition); + } + }, 0); + }; + + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (!isDropdownVisible) return; + + switch (event.key) { + case 'ArrowDown': + event.preventDefault(); + setSelectedIndex((prev) => + prev < filteredOptions.length - 1 ? prev + 1 : prev + ); + break; + case 'ArrowUp': + event.preventDefault(); + setSelectedIndex((prev) => prev > 0 ? prev - 1 : prev); + break; + case 'Enter': + event.preventDefault(); + if (filteredOptions[selectedIndex]) { + handleOptionSelect(filteredOptions[selectedIndex]); + } + break; + case 'Escape': + setDropdownVisible(false); + break; + } + }; + useEffect(() => { adjustHeight(); }, [textAreaRef?.current?.value]); @@ -74,13 +151,13 @@ const ChatInput: React.FC = ({ } }} /> - {isEditing && + {isEditing &&
} - {variableManager && + {variableManager && From d0b3e4120bf8618fd8b9a00b4cdd8496bf69d1b5 Mon Sep 17 00:00:00 2001 From: Nawaz Gafar Date: Mon, 11 Nov 2024 12:41:58 -0500 Subject: [PATCH 05/65] Added basic dropdown --- mito-ai/Untitled13.ipynb | 7 +- .../AiChat/ChatMessage/ChatDropdown.tsx | 46 ++++++++++++ .../AiChat/ChatMessage/ChatInput.tsx | 74 ++++++++++--------- 3 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 mito-ai/src/Extensions/AiChat/ChatMessage/ChatDropdown.tsx diff --git a/mito-ai/Untitled13.ipynb b/mito-ai/Untitled13.ipynb index 5f320d68d..da05f10e1 100644 --- a/mito-ai/Untitled13.ipynb +++ b/mito-ai/Untitled13.ipynb @@ -2,14 +2,17 @@ "cells": [ { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "7b3663a7-6e64-418c-bed7-9ed6b59fa7e4", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "data = {'numbers': [1], 'loan_amount': [1000], 'interest_rate': [0.05]}\n", - "simple_df = pd.DataFrame(data)" + "simple_df = pd.DataFrame(data)\n", + "\n", + "# Calculate the total amount to be paid back after one year\n", + "simple_df['total_amount'] = simple_df['loan_amount'] + (simple_df['loan_amount'] * simple_df['interest_rate'])" ] }, { diff --git a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatDropdown.tsx b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatDropdown.tsx new file mode 100644 index 000000000..8c262d50e --- /dev/null +++ b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatDropdown.tsx @@ -0,0 +1,46 @@ +import React from 'react'; + +interface ChatDropdownProps { + options: string[]; + selectedIndex: number; + onSelect: (username: string) => void; +} + +const ChatDropdown: React.FC = ({ + options, + selectedIndex, + onSelect, +}) => { + return ( +
    + {options.map((option, index) => ( +
  • onSelect(option)} + style={{ + padding: "8px", + cursor: "pointer", + backgroundColor: index === selectedIndex ? '#e6e6e6' : 'white', + }} + > + {option} +
  • + ))} +
+ ); +}; + +export default ChatDropdown; \ No newline at end of file diff --git a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx index 43edd64dc..c5ad73156 100644 --- a/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx +++ b/mito-ai/src/Extensions/AiChat/ChatMessage/ChatInput.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { classNames } from '../../../utils/classNames'; import { IVariableManager } from '../../VariableManager/VariableManagerPlugin'; +import ChatDropdown from './ChatDropdown'; interface ChatInputProps { initialContent: string; @@ -8,7 +9,7 @@ interface ChatInputProps { onSave: (content: string) => void; onCancel?: () => void; isEditing: boolean; - variableManager: IVariableManager; + variableManager?: IVariableManager; } const ChatInput: React.FC = ({ @@ -59,9 +60,9 @@ const ChatInput: React.FC = ({ if (currentWord.startsWith("@")) { const query = currentWord.slice(1); - const filtered = variableManager?.variables.filter((variable) => variable.variable_name.startsWith(query)); - setFilteredOptions(filtered?.map(v => v.variable_name) || []); - setDropdownVisible(filtered?.length > 0 || false); + const filtered = variableManager?.variables.filter((variable) => variable.variable_name.startsWith(query)) || []; + setFilteredOptions(filtered.map(v => v.variable_name)); + setDropdownVisible(filtered.length > 0); setSelectedIndex(0); } else { setDropdownVisible(false); @@ -95,45 +96,45 @@ const ChatInput: React.FC = ({ }, 0); }; - - const handleKeyDown = (event: React.KeyboardEvent) => { - if (!isDropdownVisible) return; - - switch (event.key) { - case 'ArrowDown': - event.preventDefault(); - setSelectedIndex((prev) => - prev < filteredOptions.length - 1 ? prev + 1 : prev - ); - break; - case 'ArrowUp': - event.preventDefault(); - setSelectedIndex((prev) => prev > 0 ? prev - 1 : prev); - break; - case 'Enter': - event.preventDefault(); - if (filteredOptions[selectedIndex]) { - handleOptionSelect(filteredOptions[selectedIndex]); - } - break; - case 'Escape': - setDropdownVisible(false); - break; - } - }; + // const handleKeyDown = (event: React.KeyboardEvent) => { + // if (!isDropdownVisible) return; + + // switch (event.key) { + // case 'ArrowDown': + // event.preventDefault(); + // setSelectedIndex((prev) => + // prev < filteredOptions.length - 1 ? prev + 1 : prev + // ); + // break; + // case 'ArrowUp': + // event.preventDefault(); + // setSelectedIndex((prev) => prev > 0 ? prev - 1 : prev); + // break; + // case 'Enter': + // event.preventDefault(); + // if (filteredOptions[selectedIndex]) { + // handleOptionSelect(filteredOptions[selectedIndex]); + // } + // break; + // case 'Escape': + // setDropdownVisible(false); + // break; + // } + // }; useEffect(() => { adjustHeight(); }, [textAreaRef?.current?.value]); return ( - <> +