aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DiagramBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DiagramBox.tsx')
-rw-r--r--src/client/views/nodes/DiagramBox.tsx150
1 files changed, 68 insertions, 82 deletions
diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx
index fa7e5868a..32969fa53 100644
--- a/src/client/views/nodes/DiagramBox.tsx
+++ b/src/client/views/nodes/DiagramBox.tsx
@@ -1,31 +1,23 @@
-import { makeObservable, observable, action, reaction } from 'mobx';
+import mermaid from 'mermaid';
+import { action, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
-import './DiagramBox.scss';
-import { FieldView, FieldViewProps } from './FieldView';
-import { PinProps, PresBox } from './trails';
-import mermaid from 'mermaid';
import { Doc, DocListCast } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
-import { ContextMenu } from '../ContextMenu';
-import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
-import { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
-import OpenAI, { ClientOptions } from 'openai';
-import { line } from 'd3';
-import { InkingStroke } from '../InkingStroke';
-import { DocumentManager } from '../../util/DocumentManager';
-import { C } from '@fullcalendar/core/internal-common';
+import { DocCast, NumCast } from '../../../fields/Types';
+import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
-import { NumCast } from '../../../fields/Types';
+import { DocumentManager } from '../../util/DocumentManager';
import { LinkManager } from '../../util/LinkManager';
-import { CsvCast, DocCast, StrCast } from '../../../fields/Types';
-import { DocumentType } from '../../documents/DocumentTypes';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { InkingStroke } from '../InkingStroke';
+import './DiagramBox.scss';
+import { FieldView, FieldViewProps } from './FieldView';
@observer
-export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(DiagramBox, fieldKey);
}
@@ -52,37 +44,34 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
});
this.mermaidCode = 'asdasdasd';
- 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');
+ 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') {
+ if (typeof mermaidCodeDoc[0].title === 'string') {
console.log(mermaidCodeDoc[0].title);
- if (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
+ // 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) {
- let newDoc = Docs.Create.TextDocument('mermaidCodeTitle', { title: '', x: 9999 + NumCast(this.layoutDoc._width), y: 9999 });
+ const newDoc = Docs.Create.TextDocument('mermaidCodeTitle', { title: '', x: 9999 + NumCast(this.layoutDoc._width), y: 9999 });
docViewForYourCollection.ComponentView?.addDocument(newDoc);
}
}
});
}
console.log(this.Document.title);
- //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
+ // 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),
- docs => {
- console.log('reaction happened');
- this.convertDrawingToMermaidCode();
- },
+ () => this.convertDrawingToMermaidCode(),
{ fireImmediately: true }
);
}
@@ -95,9 +84,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
return { svg: '', bindFunctions: undefined };
}
};
- mermaidDiagram = async (str: string) => {
- return await mermaid.render('graph' + Date.now(), str);
- };
+ mermaidDiagram = async (str: string) => mermaid.render('graph' + Date.now(), str);
async renderMermaidAsync(mermaidCode: string) {
try {
@@ -136,14 +123,14 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
// else{
prompt = 'Write this in mermaid code and only give me the mermaid code: ' + this.inputValue;
console.log('there is no text save');
- //}
- let res = await gptAPICall(prompt, GPTCallType.MERMAID);
+ // }
+ const res = await gptAPICall(prompt, GPTCallType.MERMAID);
this.loading = false;
- if (res == 'Error connecting with API.') {
+ if (res === 'Error connecting with API.') {
// If GPT call failed
console.error('GPT call failed');
this.errorMessage = 'GPT call failed; please try again.';
- } else if (res != null) {
+ } else if (res !== null) {
// If GPT call succeeded, set htmlCode;;; TODO: check if valid html
if (this.isValidCode(res)) {
this.mermaidCode = res;
@@ -157,55 +144,53 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
this.renderMermaidAsync.call(this, this.removeWords(this.mermaidCode));
this.loading = false;
}
- isValidCode = (html: string) => {
- return true;
- };
- removeWords(inputStr: string) {
- inputStr = inputStr.replace('```mermaid', '');
+ isValidCode = (html: string) => true;
+ removeWords(inputStrIn: string) {
+ const inputStr = inputStrIn.replace('```mermaid', '');
return inputStr.replace('```', '');
}
- //method to convert the drawings on collection node side the mermaid code
+ // method to convert the drawings on collection node side the mermaid code
async convertDrawingToMermaidCode() {
let mermaidCode = '';
let diagramExists = false;
if (this.Document.data instanceof List) {
- let docArray: Doc[] = DocListCast(this.Document.data);
- let rectangleArray = docArray.filter(doc => doc.title == 'rectangle' || doc.title == 'circle');
- let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke');
- let textArray = docArray.filter(doc => doc.type == 'rich text');
+ const docArray: Doc[] = DocListCast(this.Document.data);
+ const rectangleArray = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle');
+ const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke');
+ const textArray = docArray.filter(doc => doc.type === 'rich text');
const timeoutPromise = () =>
new Promise(resolve => {
setTimeout(resolve, 0);
});
await timeoutPromise();
- let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke);
+ const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke);
console.log(inkStrokeArray.length);
console.log(lineArray.length);
- if (inkStrokeArray[0] && inkStrokeArray.length == lineArray.length) {
+ if (inkStrokeArray[0] && inkStrokeArray.length === lineArray.length) {
mermaidCode = 'graph TD;';
- let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView);
+ const inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView);
for (let i = 0; i < rectangleArray.length; i++) {
const rectangle = rectangleArray[i];
for (let j = 0; j < lineArray.length; j++) {
- let inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX;
- let inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY;
- let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)
+ const inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX;
+ const inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY;
+ const inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)
?.inkScaledData()
.inkData.map(coord => coord.X)
.map(doc => doc * inkScaleX);
- let inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)
+ const inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)
?.inkScaledData()
.inkData.map(coord => coord.Y)
.map(doc => doc * inkScaleY);
console.log(inkingStrokeArray.length);
console.log(lineArray.length);
- //need to minX and minY to since the inkStroke.x and.y is not relative to the doc. so I have to do some calcluations
- let minX: number = Math.min(...inkStrokeXArray);
- let minY: number = Math.min(...inkStrokeYArray);
- let startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number);
- let startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number);
- let endX = inkStrokeXArray[inkStrokeXArray.length - 1] - minX + (lineArray[j].x as number);
- let endY = inkStrokeYArray[inkStrokeYArray.length - 1] - minY + (lineArray[j].y as number);
+ // need to minX and minY to since the inkStroke.x and.y is not relative to the doc. so I have to do some calcluations
+ const minX: number = Math.min(...inkStrokeXArray);
+ const minY: number = Math.min(...inkStrokeYArray);
+ const startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number);
+ const startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number);
+ const endX = inkStrokeXArray[inkStrokeXArray.length - 1] - minX + (lineArray[j].x as number);
+ const endY = inkStrokeYArray[inkStrokeYArray.length - 1] - minY + (lineArray[j].y as number);
if (this.isPointInBox(rectangle, [startX, startY])) {
for (let k = 0; k < rectangleArray.length; k++) {
const rectangle2 = rectangleArray[k];
@@ -213,8 +198,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
diagramExists = true;
const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(lineArray[j]).map(d => DocCast(LinkManager.getOppositeAnchor(d, lineArray[j])));
console.log(linkedDocs.length);
- if (linkedDocs.length != 0) {
- let linkedText = (linkedDocs[0].text as RichTextField).Text;
+ if (linkedDocs.length !== 0) {
+ const linkedText = (linkedDocs[0].text as RichTextField).Text;
mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->|' + linkedText + '|' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';';
} else {
mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';';
@@ -224,13 +209,13 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
}
}
}
- //this will save the text
+ // this will save the text
DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => {
if (docViewForYourCollection && docViewForYourCollection.ComponentView) {
if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) {
- let docArray: Doc[] = DocListCast(this.Document.data);
- docArray = docArray.filter(doc => doc.type == 'rich text');
- let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle');
+ 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;
@@ -246,24 +231,24 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
}
testInkingStroke = () => {
if (this.Document.data instanceof List) {
- let docArray: Doc[] = DocListCast(this.Document.data);
- let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke');
+ const docArray: Doc[] = DocListCast(this.Document.data);
+ const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke');
setTimeout(() => {
- let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke);
+ const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke);
console.log(inkStrokeArray);
});
}
};
getTextInBox = (box: Doc, richTextArray: Doc[]): string => {
for (let i = 0; i < richTextArray.length; i++) {
- let textDoc = richTextArray[i];
+ const textDoc = richTextArray[i];
if (typeof textDoc.x === 'number' && typeof textDoc.y === 'number' && typeof box.x === 'number' && typeof box.height === 'number' && typeof box.width === 'number' && typeof box.y === 'number') {
if (textDoc.x > box.x && textDoc.x < box.x + box.width && textDoc.y > box.y && textDoc.y < box.y + box.height) {
- if (box.title == 'rectangle') {
- return '(' + (textDoc.text as RichTextField)?.Text + ')';
+ if (box.title === 'rectangle') {
+ return '(' + ((textDoc.text as RichTextField)?.Text ?? '') + ')';
}
- if (box.title == 'circle') {
- return '((' + (textDoc.text as RichTextField)?.Text + '))';
+ if (box.title === 'circle') {
+ return '((' + ((textDoc.text as RichTextField)?.Text ?? '') + '))';
}
}
}
@@ -273,9 +258,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
isPointInBox = (box: Doc, line: number[]): boolean => {
if (typeof line[0] === 'number' && typeof box.x === 'number' && typeof box.width === 'number' && typeof box.height === 'number' && typeof box.y === 'number' && typeof line[1] === 'number') {
return line[0] < box.x + box.width && line[0] > box.x && line[1] > box.y && line[1] < box.y + box.height;
- } else {
- return false;
}
+ return false;
};
render() {
@@ -284,13 +268,15 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
<div ref={this._dragRef} className="DIYNodeBox-wrapper">
<div className="search-bar">
<input type="text" value={this.inputValue} onChange={this.handleInputChange} />
- <button onClick={this.handleRenderClick}>Generate</button>
+ <button type="button" onClick={this.handleRenderClick}>
+ Generate
+ </button>
</div>
<div className="content">
{this.mermaidCode ? (
- <div id={'dashDiv' + this.Document.title} className="diagramBox"></div>
+ <div id={'dashDiv' + this.Document.title} className="diagramBox" />
) : (
- <div>{this.loading ? <div className="loading-circle"></div> : <div>{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}</div>}</div>
+ <div>{this.loading ? <div className="loading-circle" /> : <div>{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}</div>}</div>
)}
</div>
</div>