diff options
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 093c1244c..732c4d637 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -46,6 +46,9 @@ import { OpenWhere } from '../../OpenWhere'; import { Upload } from '../../../../../server/SharedMediaTypes'; import { DocumentMetadataTool } from '../tools/DocumentMetadataTool'; import { AgentDocumentManager } from '../utils/AgentDocumentManager'; +import { AiOutlineSend } from 'react-icons/ai'; +import { SnappingManager } from '../../../../util/SnappingManager'; +import { Button, Size, Type } from '@dash/components'; dotenv.config(); @@ -111,8 +114,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { super(props); makeObservable(this); + // At mount time, find the DocumentView whose .Document is the collection container. + const parentView = DocumentView.Selected().lastElement(); + if (!parentView) { + console.warn('GPT ChatBox not inside a DocumentView – cannot sort.'); + } + this.messagesRef = React.createRef(); - this.docManager = new AgentDocumentManager(this); + this.docManager = new AgentDocumentManager(this, parentView); // Initialize OpenAI client this.initializeOpenAI(); @@ -146,6 +155,25 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } ); + /* + reaction( + () => ({ selDoc: DocumentView.Selected().lastElement(), visible: SnappingManager.ChatVisible }), + ({ selDoc, visible }) => { + const hasChildDocs = visible && selDoc?.ComponentView?.hasChildDocs; + if (hasChildDocs) { + this._textToDocMap.clear(); + this.setCollectionContext(selDoc.Document); + this.onGptResponse = (sortResult: string, questionType: GPTDocCommand) => this.processGptResponse(selDoc, this._textToDocMap, sortResult, questionType); + this.onQuizRandom = () => this.randomlyChooseDoc(selDoc.Document, hasChildDocs()); + this._documentDescriptions = Promise.all(hasChildDocs().map(doc => + Doc.getDescription(doc).then(text => this._textToDocMap.set(text.replace(/\n/g, ' ').trim(), doc) && `${DescriptionSeperator}${text}${DescriptionSeperator}`) + )).then(docDescriptions => docDescriptions.join()); // prettier-ignore + } + }, + { fireImmediately: true } + ); + }*/ + // Initialize font size from saved preference this.initFontSize(); } @@ -341,15 +369,19 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action askGPT = async (event: React.FormEvent): Promise<void> => { event.preventDefault(); + if (!this._textInputRef) { + console.log('ERROR: text input ref is undefined'); + return; + } this._inputValue = ''; // Extract the user's message - const textInput = (event.currentTarget as HTMLFormElement).elements.namedItem('messageInput') as HTMLInputElement; - const trimmedText = textInput.value.trim(); + const textInput = this._textInputRef?.value ?? ''; + const trimmedText = textInput.trim(); if (trimmedText) { + this._textInputRef.value = ''; // Clear the input field try { - textInput.value = ''; // Add the user's message to the history this._history.push({ role: ASSISTANT_ROLE.USER, @@ -485,7 +517,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action public whichDoc = (doc: parsedDoc, insideCol: boolean): Opt<Doc> => { - const options = OmitKeys(doc, ['doct_type', 'data']).omit as DocumentOptions; + const options = OmitKeys(doc, ['doc_type', 'data']).omit as DocumentOptions; const data = (doc as parsedDocData).data; const ndoc = (() => { switch (doc.doc_type) { @@ -1450,20 +1482,20 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { autoComplete="off" placeholder="Type your message here..." value={this._inputValue} - onChange={action(e => (this._inputValue = e.target.value))} + onChange={e => this.setChatInput(e.target.value)} disabled={this._isLoading} /> </div> - <button className="submit-button" onClick={() => this._dictation?.stopDictation()} type="submit" disabled={this._isLoading || !this._inputValue.trim()}> - {this._isLoading ? ( - <div className="spinner"></div> - ) : ( - <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"> - <line x1="22" y1="2" x2="11" y2="13"></line> - <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> - </svg> - )} - </button> + <Button + // className="submit-button" + onClick={this.askGPT} + type={Type.PRIM} + tooltip="Send to AI" + color={SnappingManager.userVariantColor} + inactive={this._isLoading || !this._inputValue.trim()} + icon={<AiOutlineSend />} + size={Size.LARGE} + /> <DictationButton ref={r => { this._dictation = r; @@ -1500,7 +1532,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { The tool <strong>{this._toolReloadModal.toolName}</strong> has been created and saved successfully. </p> <p>To make the tool available for future use, the page needs to be reloaded to rebuild the application bundle.</p> - <p>Click "Reload Page" to complete the tool installation.</p> + <p>Click "Reload Page" to complete the tool installation.</p> </div> <div className="tool-reload-modal-actions"> <button className="reload-button primary" onClick={this.handleReloadConfirmation}> @@ -1523,5 +1555,5 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { */ Docs.Prototypes.TemplateMap.set(DocumentType.CHAT, { layout: { view: ChatBox, dataField: 'data' }, - options: { acl: '', _layout_fitWidth: true, chat: '', chat_history: '', chat_thread_id: '', chat_assistant_id: '', chat_vector_store_id: '', _forceActive: true }, + options: { acl: '', _layout_nativeDimEditable: true, _layout_fitWidth: true, chat: '', chat_history: '', chat_thread_id: '', chat_assistant_id: '', chat_vector_store_id: '', _forceActive: true }, }); |