From 88caa55967b1dbf670b156dd08efc4f559067af7 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Mon, 19 Feb 2024 16:19:05 -0500 Subject: ai (updates from sophie, then added dataviz summary) --- .../views/nodes/formattedText/FormattedTextBox.tsx | 34 +++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f2c4c6c8f..8d5b0218d 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -8,7 +8,7 @@ import { history } from 'prosemirror-history'; import { inputRules } from 'prosemirror-inputrules'; import { keymap } from 'prosemirror-keymap'; import { Fragment, Mark, Node, Slice } from 'prosemirror-model'; -import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state'; +import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; @@ -972,9 +972,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + if (!this._editorView) return; if (resIndex < newText.length) { - const marks = this._editorView?.state.storedMarks ?? []; - this._editorView?.dispatch(this._editorView.state.tr.setStoredMarks(marks).insertText(newText[resIndex]).setStoredMarks(marks)); + const marks = this._editorView.state.storedMarks ?? []; + this._editorView.dispatch(this._editorView.state.tr.insertText(newText[resIndex]).setStoredMarks(marks)); setTimeout(() => { this.animateRes(resIndex + 1, newText); }, 20); @@ -983,15 +984,34 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { try { - let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION); + // let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION); + + let data = { + "Weight":[69,69,65,72,67,73,70,75,74,65,73,70,74,68,74,65,69,75,67,74,66,70,69,68,67,71,67,70,74,71,73,66,72,73,68,69,69,74,70,73], + "Size":[4.39,4.21,4.09,5.85,4.7,5.68,5.56,5.11,5.36,4.27,5.79,5.47,5.53,4.47,5.22,4.48,4.66,5.25,4.18,5.5,4.13,4.83,4.61,4.08,4.25,5.35,4.01,4.22,5.25,5.26,5.78,4.68,5.72,5.17,4.83,4.11,4.76,5.48,5.59,5.03], + "Class":["orange","orange","orange","apple","orange","apple","apple","apple","apple","orange","apple","apple","apple","orange","apple","orange","orange","apple","orange","apple","orange","orange","orange","orange","orange","apple","orange","orange","apple","apple","apple","orange","apple","apple","orange","orange","orange","apple","apple","apple"] + } + let input = JSON.stringify(data); + + + let res = await gptAPICall(input, GPTCallType.DATA); + console.log('GPT Result: ', res); + console.log(res); if (!res) { - console.error('GPT call failed'); this.animateRes(0, 'Something went wrong.'); } else { - this.animateRes(0, res); + if (!this._editorView) return; + // No animation + // this._editorView.dispatch(this._editorView.state.tr.insertText(res)); + + // Animation + // Set selection at end + const sel = Selection.atEnd(this._editorView.state.doc); + this._editorView.dispatch(this._editorView.state.tr.setSelection(sel)); + this.animateRes(0, '\n\n' + res); } } catch (err) { - console.error('GPT call failed'); + console.error(err); this.animateRes(0, 'Something went wrong.'); } }); -- cgit v1.2.3-70-g09d2 From b7de39e877c6fc9d3604dbc363999ac91ce3fa62 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Tue, 27 Feb 2024 16:52:00 -0500 Subject: textbox ask ai fix --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index a1e4bfacc..e5362762e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -984,19 +984,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { try { - // let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION); - - let data = { - "Weight":[69,69,65,72,67,73,70,75,74,65,73,70,74,68,74,65,69,75,67,74,66,70,69,68,67,71,67,70,74,71,73,66,72,73,68,69,69,74,70,73], - "Size":[4.39,4.21,4.09,5.85,4.7,5.68,5.56,5.11,5.36,4.27,5.79,5.47,5.53,4.47,5.22,4.48,4.66,5.25,4.18,5.5,4.13,4.83,4.61,4.08,4.25,5.35,4.01,4.22,5.25,5.26,5.78,4.68,5.72,5.17,4.83,4.11,4.76,5.48,5.59,5.03], - "Class":["orange","orange","orange","apple","orange","apple","apple","apple","apple","orange","apple","apple","apple","orange","apple","orange","orange","apple","orange","apple","orange","orange","orange","orange","orange","apple","orange","orange","apple","apple","apple","orange","apple","apple","orange","orange","orange","apple","apple","apple"] - } - let input = JSON.stringify(data); - - - let res = await gptAPICall(input, GPTCallType.DATA); - console.log('GPT Result: ', res); - console.log(res); + let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION); if (!res) { this.animateRes(0, 'Something went wrong.'); } else { -- cgit v1.2.3-70-g09d2 From 53fbe74037f03456a678d592d0ae5660c2f0d55e Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 10 Apr 2024 21:02:05 -0400 Subject: more notetaking fixes - turn off autoSize, unobserve children. fixed typing a new note to delete placeholder text. added autoCreate for columns. added pivot column selector for notetaking view. --- .../collections/CollectionNoteTakingView.scss | 9 +++ .../views/collections/CollectionNoteTakingView.tsx | 80 +++++++++++++++++----- .../collections/CollectionNoteTakingViewColumn.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 4 files changed, 73 insertions(+), 22 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/collections/CollectionNoteTakingView.scss b/src/client/views/collections/CollectionNoteTakingView.scss index 81000e7a5..95fda7b0a 100644 --- a/src/client/views/collections/CollectionNoteTakingView.scss +++ b/src/client/views/collections/CollectionNoteTakingView.scss @@ -494,6 +494,15 @@ .rc-switch-checked .rc-switch-inner { left: 8px; } + + .collectionNoteTaking-pivotField { + display: none; + } + &:hover { + .collectionNoteTaking-pivotField { + display: unset; + } + } } .collectionNoteTakingViewLight { diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 5c52d2398..d8a0aebb1 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -14,9 +14,10 @@ import { Docs, DocUtils } from '../../documents/Documents'; import { DragManager, dropActionType } from '../../util/DragManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; -import { undoBatch } from '../../util/UndoManager'; +import { undoable, undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; +import { Colors } from '../global/globalEnums'; import { LightboxView } from '../LightboxView'; import { DocumentView } from '../nodes/DocumentView'; import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView'; @@ -26,7 +27,7 @@ import './CollectionNoteTakingView.scss'; import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn'; import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider'; import { CollectionSubView } from './CollectionSubView'; -import { Colors } from '../global/globalEnums'; +import { FieldsDropdown } from '../FieldsDropdown'; const _global = (window /* browser */ || global) /* node */ as any; /** @@ -42,7 +43,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { _masonryGridRef: HTMLDivElement | null = null; _draggerRef = React.createRef(); @computed get notetakingCategoryField() { - return StrCast(this.dataDoc.notetaking_category, 'NotetakingCategory'); + return StrCast(this.dataDoc.notetaking_column, StrCast(this.layoutDoc.pivotField, 'notetaking_column')); } public DividerWidth = 16; @observable docsDraggedRowCol: number[] = []; @@ -155,25 +156,34 @@ export class CollectionNoteTakingView extends CollectionSubView() { ); }; + @computed get allFieldValues() { + return new Set(this.childDocs.map(doc => StrCast(doc[this.notetakingCategoryField]))); + } + componentDidMount() { super.componentDidMount?.(); document.addEventListener('pointerup', this.removeDocDragHighlight, true); - this._disposers.layout_autoHeight = reaction( - () => this.layoutDoc._layout_autoHeight, - layout_autoHeight => layout_autoHeight && this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))) + + this._disposers.autoColumns = reaction( + () => (this.layoutDoc._notetaking_columns_autoCreate ? Array.from(this.allFieldValues) : undefined), + columns => undoable(() => columns?.filter(col => !this.colHeaderData.some(h => h.heading === col)).forEach(col => this.addColumn(col)), 'adding columns')(), + { fireImmediately: true } ); this._disposers.refList = reaction( () => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !LightboxView.Contains(this.DocumentView?.()) }), ({ refList, autoHeight }) => { - if (autoHeight) refList.forEach(r => this.observer.observe(r)); - else this.observer.disconnect(); + if (autoHeight) { + refList.forEach(r => this.observer.observe(r)); + this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))); + } else this.observer.disconnect(); }, { fireImmediately: true } ); } componentWillUnmount() { + this.observer.disconnect(); document.removeEventListener('pointerup', this.removeDocDragHighlight, true); super.componentWillUnmount(); Object.keys(this._disposers).forEach(key => this._disposers[key]()); @@ -300,7 +310,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { getDocWidth(d: Doc) { const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as Field); const existingHeader = this.colHeaderData.find(sh => sh.heading === heading); - const existingWidth = existingHeader?.width ? existingHeader.width : 0; + const existingWidth = this.layoutDoc._notetaking_columns_autoSize ? 1 / (this.colHeaderData.length ?? 1) : existingHeader?.width ? existingHeader.width : 0; const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth; const width = d.layout_fitWidth ? maxWidth : NumCast(d._width); return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth); @@ -502,7 +512,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { editableViewProps = () => ({ GetValue: () => '', - SetValue: this.addGroup, + SetValue: this.addColumn, contents: '+ Column', }); @@ -543,18 +553,26 @@ export class CollectionNoteTakingView extends CollectionSubView() { /> ); + @undoBatch + remColumn = (value: SchemaHeaderField) => { + const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + if (value) { + const index = colHdrData.indexOf(value); + index !== -1 && colHdrData.splice(index, 1); + this.resizeColumns(colHdrData); + } + }; + // addGroup is called when adding a new columnHeader, adding a SchemaHeaderField to our list of // columnHeaders and resizing the existing columns to make room for our new one. @undoBatch - addGroup = (value: string) => { - if (this.colHeaderData) { - for (const header of this.colHeaderData) { - if (header.heading === value) { - alert('You cannot use an existing column name. Please try a new column name'); - return value; - } + addColumn = (value: string) => { + this.colHeaderData.forEach(header => { + if (header.heading === value) { + alert('You cannot use an existing column name. Please try a new column name'); + return value; } - } + }); const columnHeaders = Array.from(Cast(this.dataDoc[this.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); const newColWidth = 1 / (this.numGroupColumns + 1); columnHeaders.push(new SchemaHeaderField(value, undefined, undefined, newColWidth)); @@ -562,11 +580,25 @@ export class CollectionNoteTakingView extends CollectionSubView() { return true; }; + removeEmptyColumns = undoable(() => { + this.colHeaderData.filter(h => !this.allFieldValues.has(h.heading)).forEach(this.remColumn); + }, 'remove empty Columns'); + onContextMenu = (e: React.MouseEvent): void => { // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout if (!e.isPropagationStopped()) { const subItems: ContextMenuProps[] = []; - subItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => (this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill), icon: 'plus' }); + subItems.push({ + description: `${this.layoutDoc._notetaking_columns_autoCreate ? 'Manually' : 'Automatically'} Create columns`, + event: () => (this.layoutDoc._notetaking_columns_autoCreate = !this.layoutDoc._notetaking_columns_autoCreate), + icon: 'computer', + }); + subItems.push({ description: 'Remove Empty Columns', event: this.removeEmptyColumns, icon: 'computer' }); + subItems.push({ + description: `${this.layoutDoc._notetaking_columns_autoSize ? 'Variable Size' : 'Autosize'} Columns`, + event: () => (this.layoutDoc._notetaking_columns_autoSize = !this.layoutDoc._notetaking_columns_autoSize), + icon: 'plus', + }); subItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight), icon: 'plus' }); subItems.push({ description: 'Clear All', event: () => (this.dataDoc.data = new List([])), icon: 'times' }); ContextMenu.Instance.addItem({ description: 'Options...', subitems: subItems, icon: 'eye' }); @@ -634,6 +666,16 @@ export class CollectionNoteTakingView extends CollectionSubView() { onContextMenu={this.onContextMenu} onWheel={e => this._props.isContentActive() && e.stopPropagation()}> <>{this.renderedSections} +
+ { + this.layoutDoc._pivotField = fieldKey; + this.removeEmptyColumns(); + }, 'change pivot field')} + placeholder={StrCast(this.layoutDoc._pivotField)} + /> +
); } diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 788490b82..448b11b05 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -4,7 +4,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { lightOrDark, returnEmptyString } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; -import { Id } from '../../../fields/FieldSymbols'; import { RichTextField } from '../../../fields/RichTextField'; import { listSpec } from '../../../fields/Schema'; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; @@ -68,6 +67,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color); return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%'; @@ -154,7 +154,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (this._props.headingObject) { - this._props.docList.forEach(d => (d[this._props.pivotField] = undefined)); + // this._props.docList.forEach(d => (d[DocData][this._props.pivotField] = undefined)); colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1); this._props.resizeColumns(colHdrData); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c2f3a6e4b..5c59f7f60 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1255,7 +1255,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if (this._editorView && this._applyingChange !== this.fieldKey) { + if (this._editorView && this._applyingChange !== this.fieldKey && incomingValue?.data !== this.dataDoc[this.fieldKey]) { if (incomingValue?.data) { const updatedState = JSON.parse(incomingValue.data.Data); if (JSON.stringify(this._editorView.state.toJSON()) !== JSON.stringify(updatedState)) { -- cgit v1.2.3-70-g09d2 From d444d05ebe5eb0d72070ba21e1ae5935930b749f Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 17 Apr 2024 11:56:15 -0400 Subject: reverted fix for replacing placeholder text in a new typed note -- breaks switching from one fieldKey to another --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 5c59f7f60..c2f3a6e4b 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1255,7 +1255,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if (this._editorView && this._applyingChange !== this.fieldKey && incomingValue?.data !== this.dataDoc[this.fieldKey]) { + if (this._editorView && this._applyingChange !== this.fieldKey) { if (incomingValue?.data) { const updatedState = JSON.parse(incomingValue.data.Data); if (JSON.stringify(this._editorView.state.toJSON()) !== JSON.stringify(updatedState)) { -- cgit v1.2.3-70-g09d2 From 62937027183dc8acf14e489fbb4590aff6fce2cd Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 17 Apr 2024 12:25:17 -0400 Subject: fix problem where placeholder text of note wasn't being overwritten. --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c2f3a6e4b..a2db2a1cc 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1484,6 +1484,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent Date: Wed, 24 Apr 2024 18:36:52 -0400 Subject: minor tweaks for merging --- src/client/apis/gpt/GPT.ts | 6 +++--- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index c97d29d6f..30194f9f8 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -43,7 +43,7 @@ const gptAPICall = async (inputText: string, callType: GPTCallType, prompt?: any }; const openai = new OpenAI(configuration); - let usePrompt = prompt? opts.prompt+prompt: opts.prompt; + let usePrompt = prompt ? opts.prompt + prompt : opts.prompt; let messages: ChatCompletionMessageParam[] = [ { role: 'system', content: usePrompt }, { role: 'user', content: inputText }, @@ -51,9 +51,9 @@ const gptAPICall = async (inputText: string, callType: GPTCallType, prompt?: any const response = await openai.chat.completions.create({ model: opts.model, - messages: messages, - temperature: opts.temp, max_tokens: opts.maxTokens, + temperature: opts.temp, + messages, }); const content = response.choices[0].message.content; return content; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bb910737b..36c1de841 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -984,13 +984,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if (!this._editorView) return; if (resIndex < newText.length) { - const marks = this._editorView.state.storedMarks ?? []; - this._editorView.dispatch(this._editorView.state.tr.insertText(newText[resIndex]).setStoredMarks(marks)); - setTimeout(() => { - this.animateRes(resIndex + 1, newText); - }, 20); + const marks = this._editorView?.state.storedMarks ?? []; + this._editorView?.dispatch(this._editorView?.state.tr.insertText(newText[resIndex]).setStoredMarks(marks)); + setTimeout(() => this.animateRes(resIndex + 1, newText), 20); } }; -- cgit v1.2.3-70-g09d2 From ae9404e2c80555875f2fd69f4ae55105ae51168b Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 24 Apr 2024 18:44:28 -0400 Subject: from last --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 36c1de841..a46b19a85 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -996,15 +996,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent