diff options
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx | 114 |
1 files changed, 54 insertions, 60 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 83b50c8c6..076f49831 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -14,7 +14,7 @@ import OpenAI, { ClientOptions } from 'openai'; import * as React from 'react'; import { v4 as uuidv4 } from 'uuid'; import { ClientUtils } from '../../../../../ClientUtils'; -import { Doc, DocListCast, Opt } from '../../../../../fields/Doc'; +import { Doc, DocListCast, FieldType, Opt } from '../../../../../fields/Doc'; import { DocData, DocViews } from '../../../../../fields/DocSymbols'; import { CsvCast, DocCast, NumCast, PDFCast, RTFCast, StrCast } from '../../../../../fields/Types'; import { Networking } from '../../../../Network'; @@ -324,7 +324,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { processing_info: [], }); } finally { - this._isLoading = false; + runInAction(() => { + this._isLoading = false; + }); this.scrollToBottom(); } } @@ -402,19 +404,17 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { data.map(doc => doc.doc_type !== 'collection' // Handle non-collection documents ? this.whichDoc(doc.doc_type, doc.data, { backgroundColor: doc.backgroundColor, _width: doc.width, _height: doc.height }, doc.id, insideCol) - : // Recursively process collections - this.createCollectionWithChildren(doc.data, true).then(nestedDocs => - Docs.Create.FreeformDocument(nestedDocs, { - title: doc.title, - backgroundColor: doc.backgroundColor, - _width: doc.width, - _height: doc.height, - _layout_fitWidth: true, - _freeform_backgroundGrid: true, - }) - ) - ) - .flat() // prettier-ignore + : this.createCollectionWithChildren(doc.data, true).then(nestedDocs => + Docs.Create.FreeformDocument(nestedDocs, { + title: doc.title, + backgroundColor: doc.backgroundColor, + _width: doc.width, + _height: doc.height, + _layout_fitWidth: true, + _freeform_backgroundGrid: true, + }) + ) + ) // prettier-ignore ).then(childDocs => childDocs.filter(doc => doc).map(doc => doc!)); // .then(nestedResults => { // // Flatten any nested arrays from recursive collection calls @@ -427,23 +427,18 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // return childDocs; // }); - // @action - // createSingleFlashcard = (data: any, options: DocumentOptions) => { - - // } - @action - whichDoc = (doc_type: string, data: string, options: DocumentOptions, id: string, insideCol: boolean): Promise<Opt<Doc>> => + whichDoc = (doc_type: string, data: unknown, options: DocumentOptions, id: string, insideCol: boolean): Promise<Opt<Doc>> => (async () => { switch (doc_type) { - case 'text': return Docs.Create.TextDocument(data, options); - case 'flashcard': return this.createFlashcard(data, options); - case 'deck': return this.createDeck(data, options); - case 'image': return Docs.Create.ImageDocument(data, options); - case 'equation': return Docs.Create.EquationDocument(data, options); + case 'text': return Docs.Create.TextDocument(data as string, options); + case 'flashcard': return this.createFlashcard(data as string[], options); + case 'deck': return this.createDeck(data as string, options); + case 'image': return Docs.Create.ImageDocument(data as string, options); + case 'equation': return Docs.Create.EquationDocument(data as string, options); case 'noteboard': return Docs.Create.NoteTakingDocument([], options); case 'simulation': return Docs.Create.SimulationDocument(options); - case 'collection': return this.createCollectionWithChildren(data as any, true). + case 'collection': return this.createCollectionWithChildren(data as { doc_type: string; id: string; data: any; title: string; width: number; height: number; backgroundColor: string }[] , true). then((arr, collOpts = { ...options, _layout_fitWidth: true, _freeform_backgroundGrid: true }) => (() => { switch (options.type_collection) { @@ -457,10 +452,10 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } })() ); - case 'web': return Docs.Create.WebDocument(data, { ...options, data_useCors: true }); - case 'comparison': return this.createComparison(data, options); + case 'web': return Docs.Create.WebDocument(data as string, { ...options, data_useCors: true }); + case 'comparison': return this.createComparison(data as {left: {width:number ,height: number, backgroundColor: string, data: string}, right: {width:number ,height: number, backgroundColor: string, data: string}}, options); case 'diagram': return Docs.Create.DiagramDocument(options); - case 'audio': return Docs.Create.AudioDocument(data, options); + case 'audio': return Docs.Create.AudioDocument(data as string, options); case 'map': return Docs.Create.MapDocument([], options); case 'screengrab': return Docs.Create.ScreenshotDocument(options); case 'webcam': return Docs.Create.WebCamDocument('', options); @@ -471,7 +466,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { case 'trail': return Docs.Create.PresDocument(options); case 'tab': return Docs.Create.FreeformDocument([], options); case 'slide': return Docs.Create.TreeDocument([], options); - default: return Docs.Create.TextDocument(data, options); + default: return Docs.Create.TextDocument(data as string, options); } // prettier-ignore })().then(doc => { if (doc) { @@ -491,7 +486,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Promise<void>} A promise that resolves once the document is created and displayed. */ @action - createDocInDash = (doc_type: string, data: string | undefined, options: DocumentOptions, id: string) => { + createDocInDash = (doc_type: string, data: unknown, options: DocumentOptions /*, id: string */) => { const linkAndShowDoc = (doc: Opt<Doc>) => { if (doc) { LinkManager.Instance.addLink(Docs.Create.LinkDocument(this.Document, doc)); @@ -501,22 +496,21 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; const doc = (() => { switch (doc_type.toLowerCase()) { - case 'text': return Docs.Create.TextDocument(data || '', options); - case 'image': return Docs.Create.ImageDocument(data || '', options); - case 'pdf': return Docs.Create.PdfDocument(data || '', options); - case 'video': return Docs.Create.VideoDocument(data || '', options); - case 'audio': return Docs.Create.AudioDocument(data || '', options); - case 'web': return Docs.Create.WebDocument(data || '', options); - case 'equation': return Docs.Create.EquationDocument(data || '', options); + case 'flashcard': return this.createFlashcard(data as string[], options); + case 'text': return Docs.Create.TextDocument(data as string || '', options); + case 'image': return Docs.Create.ImageDocument(data as string || '', options); + case 'pdf': return Docs.Create.PdfDocument(data as string || '', options); + case 'video': return Docs.Create.VideoDocument(data as string || '', options); + case 'audio': return Docs.Create.AudioDocument(data as string || '', options); + case 'web': return Docs.Create.WebDocument(data as string || '', options); + case 'equation': return Docs.Create.EquationDocument(data as string || '', options); case 'chat': return Docs.Create.ChatDocument(options); - case 'functionplot': - case 'function_plot': return Docs.Create.FunctionPlotDocument([], options); - case 'dataviz': - case 'data_viz': Networking.PostToServer('/createCSV', { + case 'functionplot': return Docs.Create.FunctionPlotDocument([], options); + case 'dataviz': Networking.PostToServer('/createCSV', { filename: (options.title as string).replace(/\s+/g, '') + '.csv', data: data, })?.then(({ fileUrl, id }) => { - const vdoc = Docs.Create.DataVizDocument(fileUrl, { ...options, text: RTFCast(data) }); + const vdoc = Docs.Create.DataVizDocument(fileUrl, { ...options, text: RTFCast(data as FieldType) }); this.addCSVForAnalysis(vdoc, id); linkAndShowDoc(vdoc); }); @@ -537,14 +531,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc} A carousel document containing the flashcard deck. */ @action - createDeck = (data: any, options: DocumentOptions) => { + createDeck = (data: string | unknown[], options: DocumentOptions) => { const flashcardDeck: Doc[] = []; // Parse `data` only if it’s a string - const deckData = typeof data === 'string' ? JSON.parse(data) : data; - const flashcardArray = Array.isArray(deckData) ? deckData : Object.values(deckData); + const deckData = typeof data === 'string' ? (JSON.parse(data) as unknown) : data; + const flashcardArray = Array.isArray(deckData) ? deckData : Object.values(deckData as object); // Process each flashcard document in the `deckData` array if (flashcardArray.length == 2 && flashcardArray[0].doc_type == 'text' && flashcardArray[1].doc_type == 'text') { - this.createFlashcard(flashcardArray, options); + this.createFlashcard(flashcardArray as string[], options); } else { flashcardArray.forEach(doc => { const flashcardDoc = this.createFlashcard(doc, options); @@ -570,24 +564,24 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc | undefined} The created flashcard document, or undefined if the flashcard cannot be created. */ @action - createFlashcard = (data: any, options: any) => { + createFlashcard = (data: string[], options: DocumentOptions) => { const deckData = typeof data === 'string' ? JSON.parse(data) : data; - const flashcardArray = Array.isArray(deckData) ? deckData : Object.values(deckData)[2]; + const flashcardArray = Array.isArray(deckData) ? deckData : (Object.values(deckData)[2] as string[]); const [front, back] = flashcardArray; - if (front.doc_type === 'text' && back.doc_type === 'text') { + if (typeof front === 'string' && typeof back === 'string') { const sideOptions: DocumentOptions = { backgroundColor: options.backgroundColor, _width: options._width, - _height: options._height, + _height: options._height || 300, }; // Create front and back text documents - const side1 = Docs.Create.CenteredTextCreator(front.title, front.data, sideOptions); - const side2 = Docs.Create.CenteredTextCreator(back.title, back.data, sideOptions); + const side1 = Docs.Create.CenteredTextCreator('question', front, sideOptions); + const side2 = Docs.Create.CenteredTextCreator('answer', back, sideOptions); // Create the flashcard document with both sides - return Docs.Create.FlashcardDocument(data.title, side1, side2, sideOptions); + return Docs.Create.FlashcardDocument('flashcard', side1, side2, sideOptions); } }; @@ -599,12 +593,12 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc} The created comparison document. */ @action - createComparison = (doc: { left: any; right: any }, options: any) => - Docs.Create.ComparisonDocument(options.title, { + createComparison = (doc: { left: { width: number; height: number; backgroundColor: string; data: string }; right: { width: number; height: number; backgroundColor: string; data: string } }, options: DocumentOptions) => + Docs.Create.ComparisonDocument(options.title as string, { data_back: Docs.Create.TextDocument(doc.left.data, { backgroundColor: doc.left.backgroundColor, _width: doc.left.width, _height: doc.left.height }), data_front: Docs.Create.TextDocument(doc.right.data, { backgroundColor: doc.right.backgroundColor, _width: doc.right.width, _height: doc.right.height }), - _width: options.width, - _height: options.height | 300, + _width: options._width, + _height: options._height || 300, backgroundColor: options.backgroundColor, }); @@ -909,7 +903,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { </div> <form onSubmit={this.askGPT} className="chat-input"> - <input type="text" name="messageInput" autoComplete="off" placeholder="Type your message here..." value={this._inputValue} onChange={e => (this._inputValue = e.target.value)} disabled={this._isLoading} /> + <input type="text" name="messageInput" autoComplete="off" placeholder="Type your message here..." value={this._inputValue} onChange={action(e => (this._inputValue = e.target.value))} disabled={this._isLoading} /> <button className="submit-button" type="submit" disabled={this._isLoading || !this._inputValue.trim()}> {this._isLoading ? ( <div className="spinner"></div> |