diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DiagramBox.scss | 32 | ||||
-rw-r--r-- | src/client/views/nodes/DiagramBox.tsx | 198 |
3 files changed, 156 insertions, 76 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index e095bc659..8ece897f4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -398,7 +398,7 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)}, { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)}, - { toolTip: "Tap or drag to create an iamge", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)}, + { toolTip: "Tap or drag to create an image", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)}, { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)}, { toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)}, { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)}, diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index b3d50a4bd..64b0e6c0e 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -3,9 +3,27 @@ height: 100%; display: flex; flex-direction: column; - align-items: center; - justify-content: center; - + .buttonCollections{ + display: flex; + justify-content: center; + flex-direction: column; + height:100%; + button{ + font-size:10px; + margin:5px; + height:100%; + width:30%; + border: none; + border-radius: 5px; + cursor: pointer; + background-color: #007bff; + color: #fff; + transition: background-color 0.3s ease; + } + button:hover { + background-color: #0056b3; + } + } .DiagramBox-wrapper { width: 100%; height: 100%; @@ -13,6 +31,11 @@ flex-direction: column; align-items: center; justify-content: center; + .backButton{ + position: absolute; + top:0; + left:0; + } .search-bar { display: flex; flex-wrap: wrap; @@ -23,10 +46,9 @@ textarea { flex: 1; - height:5px; + height: 5px; margin-right: 10px; min-height: 20px; - height:auto; resize:none; overflow: hidden; } diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index af4410394..a294ed75c 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ import mermaid from 'mermaid'; import { action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -5,7 +6,7 @@ import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { RichTextField } from '../../../fields/RichTextField'; -import { DocCast, NumCast } from '../../../fields/Types'; +import { DocCast } from '../../../fields/Types'; import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; @@ -16,6 +17,14 @@ import { InkingStroke } from '../InkingStroke'; import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; +enum menuState { + option, + mermaidCode, + drawing, + gpt, + justCreated, +} + @observer export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { @@ -27,7 +36,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { super(props); makeObservable(this); } - + @observable menuState = menuState.justCreated; + @observable renderDiv: React.ReactNode; @observable inputValue = ''; @observable loading = false; @observable errorMessage = ''; @@ -46,31 +56,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { gantt: { useMaxWidth: true, useWidth: 2000 }, }); this.mermaidCode = 'a'; - const docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCodeDoc = docArray.filter(doc => doc.type === 'rich text'); - mermaidCodeDoc = mermaidCodeDoc.filter(doc => (doc.text as RichTextField).Text === 'mermaidCodeTitle'); - if (mermaidCodeDoc[0]) { - if (typeof mermaidCodeDoc[0].title === 'string') { - console.log(mermaidCodeDoc[0].title); - if (mermaidCodeDoc[0].title !== '') { - this.renderMermaidAsync(mermaidCodeDoc[0].title); - } - } - } - // this will create a text doc far away where the user cant to save the mermaid code, where it will then be accessed when flipped to the diagram box side - // the code is stored in the title since it is much easier to change than in the text - else { - DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) { - const newDoc = Docs.Create.TextDocument('mermaidCodeTitle', { title: '', x: 9999 + NumCast(this.layoutDoc._width), y: 9999 }); - docViewForYourCollection.ComponentView?.addDocument(newDoc); - } - } - }); + if (typeof this.Document.mermaidCode === 'string') { + this.renderMermaidAsync(this.Document.mermaidCode); } console.log(this.Document.title); - this.renderMermaidAsync(this.timeline); + // this.renderMermaidAsync(this.timeline); // this is so that ever time a new doc, text node or ink node, is created, this.createMermaidCode will run which will create a save reaction( () => DocListCast(this.Document.data), @@ -86,6 +76,31 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { { fireImmediately: true } ); } + componentDidUpdate = () => { + if (typeof this.Document.mermaidCode === 'string' && this.Document.menuState === 'drawing') { + this.renderMermaidAsync(this.Document.mermaidCode); + } + }; + switchRenderDiv() { + switch (this.Document.menuState) { + case 'option': + this.renderDiv = this.renderOption(); + break; + case 'drawing': + this.renderDiv = this.renderDrawing(); + break; + case 'gpt': + this.renderDiv = this.renderGpt(); + break; + case 'mermaidCode': + this.renderDiv = this.renderMermaidCode(); + break; + default: + this.menuState = menuState.option; + this.renderDiv = this.renderOption(); + console.log(this.renderDiv); + } + } renderMermaid = async (str: string) => { try { const { svg, bindFunctions } = await this.mermaidDiagram(str); @@ -119,20 +134,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { console.log('Generating Mermaid Code'); this.loading = true; let prompt = ''; - // let docArray: Doc[] = DocListCast(this.Document.data); - // let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') - // mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') - // if(mermaidCodeDoc[0]){ - // console.log(mermaidCodeDoc[0].title) - // if(typeof mermaidCodeDoc[0].title=='string'){ - // console.log(mermaidCodeDoc[0].title) - // if(mermaidCodeDoc[0].title!=""){ - // prompt="Edit this code "+this.inputValue+": "+mermaidCodeDoc[0].title - // console.log("you have to see me") - // } - // } - // } - // else{ prompt = 'Write this in mermaid code and only give me the mermaid code: ' + this.inputValue; console.log('there is no text save'); // } @@ -222,22 +223,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } } // this will save the text - DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) { - let docs: Doc[] = DocListCast(this.Document.data); - docs = docs.filter(doc => doc.type === 'rich text'); - const mermaidCodeDoc = docs.filter(doc => (doc.text as RichTextField).Text === 'mermaidCodeTitle'); - if (mermaidCodeDoc[0]) { - if (diagramExists) { - mermaidCodeDoc[0].title = mermaidCode; - } else { - mermaidCodeDoc[0].title = ''; - } - } - } - } - }); + if (diagramExists) { + this.Document.mermaidCode = mermaidCode; + } else { + this.Document.mermaidCode = ''; + } } } } @@ -277,6 +267,87 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { element.style.height = '5px'; element.style.height = element.scrollHeight + 'px'; } + drawingButton = () => { + this.Document.menuState = 'drawing'; + }; + gptButton = () => { + this.Document.menuState = 'gpt'; + }; + mermaidButton = () => { + this.Document.menuState = 'mermaidCode'; + }; + optionButton = () => { + this.Document.menuState = 'option'; + }; + renderOption(): React.ReactNode { + return ( + <div className="buttonCollections"> + <button type="button" onClick={this.drawingButton}> + Drawing + </button> + <button type="button" onClick={this.gptButton}> + GPT + </button> + <button type="button" onClick={this.mermaidButton}> + Mermaid Code + </button> + </div> + ); + } + renderDrawing (): React.ReactNode { + return ( + <div ref={this._dragRef} className="DiagramBox-wrapper"> + <button type="button" className="backButton" onClick={this.optionButton}> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> + <path d="M0 0h24v24H0z" fill="none" /> + <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" /> + </svg> + </button> + <div className="content"> + <div id={'dashDiv' + this.Document.title} className="diagramBox" /> + </div> + </div> + ); + } + + renderGpt(): React.ReactNode { + return ( + <div ref={this._dragRef} className="DiagramBox-wrapper"> + <button type="button" className="backButton" onClick={this.optionButton}> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> + <path d="M0 0h24v24H0z" fill="none" /> + <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" /> + </svg> + </button> + <div className="search-bar"> + <textarea value={this.inputValue} onChange={this.handleInputChange} onInput={e => this.autoResize(e.target as HTMLTextAreaElement)} /> + <button type="button" onClick={this.handleRenderClick}> + Generate + </button> + </div> + <div className="content"> + {this.mermaidCode ? ( + <div id={'dashDiv' + this.Document.title} className="diagramBox" /> + ) : ( + <div>{this.loading ? <div className="loading-circle" /> : <div>{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}</div>}</div> + )} + </div> + </div> + ); + } + + renderMermaidCode(): React.ReactNode { + return ( + <div ref={this._dragRef} className="DiagramBox-wrapper"> + <button className="backButton" type="button" onClick={this.optionButton}> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> + <path d="M0 0h24v24H0z" fill="none" /> + <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" /> + </svg> + </button> + </div> + ); + } timeline = `gantt title College Timeline dateFormat YYYY-MM-DD @@ -303,23 +374,10 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { Final Exams : des16, 2025-05-10, 2025-05-15 Graduation : des17, 2025-05-20, 2025-05-21`; render() { + this.switchRenderDiv(); return ( <div ref={this._ref} className="DiagramBox"> - <div ref={this._dragRef} className="DiagramBox-wrapper"> - <div className="search-bar"> - <textarea value={this.inputValue} onChange={this.handleInputChange} onInput={e => this.autoResize(e.target as HTMLTextAreaElement)} /> - <button type="button" onClick={this.handleRenderClick}> - Generate - </button> - </div> - <div className="content"> - {this.mermaidCode ? ( - <div id={'dashDiv' + this.Document.title} className="diagramBox" /> - ) : ( - <div>{this.loading ? <div className="loading-circle" /> : <div>{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}</div>}</div> - )} - </div> - </div> + {this.renderDiv} </div> ); } |