From 0c68bfcf4041558edf94f2898fc0531f24433351 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 9 Jul 2024 03:12:28 -0400 Subject: started doccreatormenu for dataviz --- src/client/views/nodes/DataVizBox/DocCreatorMenu.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu.scss (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss new file mode 100644 index 000000000..fea5a6f59 --- /dev/null +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -0,0 +1,12 @@ +.docCreatorMenu-cont { + position: absolute; + display: flex; + min-width: 300px; + min-height: 400px; + z-index: 6; + box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%); + flex-direction: column; + background: whitesmoke; + color: black; + border-radius: 3px; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From b669b8c82efa9217cf065e670c7f6111b096f20d Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 10 Jul 2024 02:11:46 -0400 Subject: docCreatorMenu progress --- src/client/views/ContextMenu.tsx | 1 - src/client/views/MainView.tsx | 3 + src/client/views/nodes/DataVizBox/DataVizBox.tsx | 9 +- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 59 ++++++++-- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 119 +++++++++++++++++---- 5 files changed, 157 insertions(+), 34 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index d784a14b8..de985263d 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -269,7 +269,6 @@ export class ContextMenu extends ObservableReactComponent<{}> { // if (this._searchString.startsWith(this._defaultPrefix)) { this._defaultItem?.(this._searchString.substring(this._defaultPrefix.length)); } - this.closeMenu(); e.preventDefault(); e.stopPropagation(); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5b9ddbb88..926e5fd55 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -76,6 +76,7 @@ import { PresBox } from './nodes/trails'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; +import { DocCreatorMenu } from './nodes/DataVizBox/DocCreatorMenu'; const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore const _global = (window /* browser */ || global) /* node */ as any; @@ -278,6 +279,7 @@ export class MainView extends ObservableReactComponent<{}> { library.add( ...[ + fa.faWindowMaximize, fa.faGift, fa.faLockOpen, fa.faSort, @@ -1093,6 +1095,7 @@ export class MainView extends ObservableReactComponent<{}> { + diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index dae535ba6..1e0a72a91 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -429,12 +429,12 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { this.layoutDoc.dataViz_filterSelection = !this.layoutDoc.dataViz_filterSelection; }; - specificContextMenu = (): void => { + specificContextMenu = (x: number, y: number): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); const optionItems = options && 'subitems' in options ? options.subitems : []; optionItems.push({ description: `Analyze with AI`, event: () => this.askGPT(), icon: 'lightbulb' }); - optionItems.push({ description: `Create documents`, event: () => DocCreatorMenu.Instance.displayMenu(200, 200), icon: 'table-cells' }); + optionItems.push({ description: `Create documents`, event: () => DocCreatorMenu.Instance.toggleDisplay(x, y), icon: 'table-cells' }); !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' }); }; @@ -518,8 +518,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { // displays how to get data into the DataVizBox if its empty
To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command (ctrl + p) to bring the data table to your canvas.
) : ( -
-
() { transform: `scale(${scale})`, position: 'absolute', }} - onContextMenu={this.specificContextMenu} + onContextMenu={(e) => this.specificContextMenu(e.pageX, e.pageY)} onWheel={e => e.stopPropagation()} ref={this._mainCont}>
@@ -596,7 +594,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { /> )}
-
); } } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index fea5a6f59..43053ee34 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -1,12 +1,55 @@ .docCreatorMenu-cont { position: absolute; - display: flex; - min-width: 300px; - min-height: 400px; - z-index: 6; - box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%); - flex-direction: column; - background: whitesmoke; - color: black; + z-index: 100000; + // box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%); + // background: whitesmoke; + // color: black; border-radius: 3px; +} + +.docCreatorMenu-menu { + display: flex; + flex-direction: row; +} + +.docCreatorMenu-menu-button { + width: 30px; + height: 30px; + background: whitesmoke; + background-color: rgb(34, 34, 37); + border-radius: 5px; + border: 1px solid whitesmoke; + padding: 0px; + font-size: 14px; + + &.right{ + margin-left: auto; + font-size: 12px; + } + + &.close-menu { + margin-left: 0px; + font-size: 12px; + } + + &.options { + margin-left: 0px; + } + + &:hover { + background-color: rgb(60, 60, 65); + } +} + +.docCreatorMenu-menu-hr{ + margin-top: 0px; + margin-bottom: 0px; +} + +.docCreatorMenu-content { + margin: 5px; + width: calc(100% - 10px); + height: calc(100% - 51px); + border: 1px solid whitesmoke; + border-radius: 5px; } \ No newline at end of file diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index d5c2bc227..dbd385047 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -1,16 +1,25 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { SnappingManager } from '../../../util/SnappingManager'; import './DocCreatorMenu.scss'; import { ObservableReactComponent } from '../../ObservableReactComponent'; +import { IconButton, Size } from 'browndash-components'; +import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; +import { emptyFunction } from '../../../../Utils'; +import { undoable } from '../../../util/UndoManager'; +import { DragManager } from '../../../util/DragManager'; +import { DocumentView } from '../DocumentView'; +import { dropActionType } from '../../../util/DropActionTypes'; @observer export class DocCreatorMenu extends ObservableReactComponent<{}> { static Instance: DocCreatorMenu; + private _ref: HTMLDivElement | null = null; + private _reactionDisposer?: IReactionDisposer; @observable _pageX: number = 0; @@ -22,8 +31,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _mouseX: number = -1; @observable _mouseY: number = -1; + @observable _startPos: {x: number, y: number} | undefined = undefined; @observable _shouldDisplay: boolean = false; + @observable _menuContent: 'templates' | 'options' = 'templates'; + @observable _dragging: boolean = false; + constructor(props: any) { super(props); makeObservable(this); @@ -35,6 +48,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { this._mouseX = e.clientX; this._mouseY = e.clientY; }; + @action onPointerUp = (e: PointerEvent) => { if (e.button !== 2 && !e.ctrlKey) return; @@ -43,10 +57,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { if (Math.abs(this._mouseX - curX) > 1 || Math.abs(this._mouseY - curY) > 1) { this._shouldDisplay = false; } - - if (this._shouldDisplay) { - this._display = true; - } }; componentDidMount() { @@ -67,18 +77,18 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return this._pageX + DocCreatorMenu.width > window.innerWidth - DocCreatorMenu.buffer ? window.innerWidth - DocCreatorMenu.buffer - DocCreatorMenu.width : Math.max(0, this._pageX); } - get pageY() { - return this._pageY + DocCreatorMenu.height > window.innerHeight - DocCreatorMenu.buffer ? window.innerHeight - DocCreatorMenu.buffer - DocCreatorMenu.height : Math.max(0, this._pageY); - } - @action - displayMenu = (x: number, y: number) => { + toggleDisplay = (x: number, y: number) => { // maxX and maxY will change if the UI/font size changes, but will work for any amount // of items added to the menu - - this._pageX = x; - this._pageY = y; - this._shouldDisplay = true; + if (this._shouldDisplay) { + this._shouldDisplay = false; + } else { + this._pageX = x; + console.log(y); + this._pageY = y; + this._shouldDisplay = true; + } }; @action @@ -89,21 +99,92 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return wasOpen; }; + @action + onPointerMove = (e: any) => { + if (this._dragging){ + this._pageX = e.pageX - (this._startPos?.x ?? 0); + this._pageY = e.pageY - (this._startPos?.y ?? 0); + } + } + + setDragStart = () => { + + } + render() { return (
this._ref = r} style={{ display: '', - left: this.pageX, - ...(this._yRelativeToTop ? { top: Math.max(0, this.pageY) } : { bottom: this.pageY }), + left: this._pageX, + top: this._pageY, + width: this._shouldDisplay ? 300 : 0, + height: this._shouldDisplay ? 400 : 0, background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, }}> {!this._shouldDisplay ? undefined : -
hi hi
- - + <> +
+ setupMoveUpEvents( + this, + e, + (e) => { + this._dragging = true; + this._startPos = {x: 0, y: 0}; + this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0); + this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0); + return true; + }, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + }, 'open actions menu') + ) + + } + onPointerMove={e => this.onPointerMove(e)} + onPointerUp={() => this._dragging = false} + > + + + +
+
+
+ {this._menuContent === 'templates' ? +
+
+ : +
+
+ } +
+ }
) -- cgit v1.2.3-70-g09d2 From 3db8305f45233850031eaee1f19436ee7034df59 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 10 Jul 2024 03:15:43 -0400 Subject: menu progress --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 14 ++++++- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 46 ++++++++++++++++------ 2 files changed, 46 insertions(+), 14 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 43053ee34..dc0f99cbd 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -46,10 +46,22 @@ margin-bottom: 0px; } -.docCreatorMenu-content { +.docCreatorMenu-preview-content { + display: grid; + grid-template-columns: repeat(2, 1fr); + overflow-y: scroll; margin: 5px; width: calc(100% - 10px); height: calc(100% - 51px); border: 1px solid whitesmoke; border-radius: 5px; + + .docCreatorMenu-preview-window { + width: 125px; + height: 125px; + margin-top: 10px; + margin-left: 10px; + border: 1px solid whitesmoke; + border-radius: 5px; + } } \ No newline at end of file diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index dbd385047..520dd9c2d 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -79,8 +79,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action toggleDisplay = (x: number, y: number) => { - // maxX and maxY will change if the UI/font size changes, but will work for any amount - // of items added to the menu if (this._shouldDisplay) { this._shouldDisplay = false; } else { @@ -107,8 +105,24 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } - setDragStart = () => { + get templatesPreviewContents(){ + const tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + return ( +
+ {tempArray.map(i => +
+ +
)} +
+ ); + } + get optionsMenuContents(){ + return ( +
+ ); } render() { @@ -167,7 +181,21 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { > -

-
- {this._menuContent === 'templates' ? -
-
- : -
-
- } -
+ {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} } -- cgit v1.2.3-70-g09d2 From 77bf838bebc813d476788fabed6bc7bcbf8197b0 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:36:39 -0400 Subject: images displaying --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 13 ++-- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 54 +++++++++++++-- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 80 +++++++++++++--------- 3 files changed, 107 insertions(+), 40 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 1e0a72a91..f75ba9700 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -429,12 +429,18 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { this.layoutDoc.dataViz_filterSelection = !this.layoutDoc.dataViz_filterSelection; }; + openDocCreatorMenu = (x: number, y: number) => { + DocCreatorMenu.Instance.toggleDisplay(x, y); + DocCreatorMenu.Instance.setDataViz(this); + DocCreatorMenu.Instance.setTemplateDocs(this.getPossibleTemplates()); + } + specificContextMenu = (x: number, y: number): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); const optionItems = options && 'subitems' in options ? options.subitems : []; optionItems.push({ description: `Analyze with AI`, event: () => this.askGPT(), icon: 'lightbulb' }); - optionItems.push({ description: `Create documents`, event: () => DocCreatorMenu.Instance.toggleDisplay(x, y), icon: 'table-cells' }); + optionItems.push({ description: `Create documents`, event: () => this.openDocCreatorMenu(x, y), icon: 'table-cells' }); !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' }); }; @@ -452,13 +458,12 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { getPossibleTemplates = (): Doc[] => { const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(this.Document).map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document))); const linkedCollections: Doc[] = linkedDocs.filter(doc => doc.type === 'config').filter(doc => DocCast(doc.annotationOn).type === 'collection'); - console.log('cols: ' + linkedCollections) const isColumnTitle = (title: string): boolean => { const colTitles: string[] = Object.keys(this.records[0]); console.log('titles: ' + colTitles) for (let i = 0; i < colTitles.length; ++i){ if (colTitles[i] === title) { - console.log(true); + console.log(true); return true; } } @@ -472,7 +477,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { } return false; } - return linkedCollections.filter(col => isValidTemplate(col)); + return linkedDocs; } /** diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index dc0f99cbd..43d4ed7e5 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -23,13 +23,13 @@ font-size: 14px; &.right{ - margin-left: auto; + margin-left: 0px; font-size: 12px; } &.close-menu { - margin-left: 0px; font-size: 12px; + margin-left: auto; } &.options { @@ -46,7 +46,7 @@ margin-bottom: 0px; } -.docCreatorMenu-preview-content { +.docCreatorMenu-preview-container { display: grid; grid-template-columns: repeat(2, 1fr); overflow-y: scroll; @@ -64,4 +64,50 @@ border: 1px solid whitesmoke; border-radius: 5px; } -} \ No newline at end of file +} + +.docCreatorMenu-options-container { + display: flex; + overflow-y: scroll; + margin: 5px; + width: calc(100% - 10px); + height: calc(100% - 51px); + border: 1px solid whitesmoke; + border-radius: 5px; + + .docCreatorMenu-dropdown-button{ + display: flex; + width: 120px; + height: 30px; + background: whitesmoke; + background-color: rgb(34, 34, 37); + border-radius: 5px; + border: 1px solid whitesmoke; + padding: 0px; + font-size: 13px; + margin: 10px; + align-content: center; + justify-content: center; + text-transform: uppercase; + + // &:hover .docCreatorMenu-dropdown-content{ + // display: block; + // } + } + + .docCreatorMenu-dropdown-content { + display: none; + position: absolute; + min-width: 100px; + z-index: 1; + + .docCreatorMenu-dropdown-option{ + display: block; + } + + } + + + +} + diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 520dd9c2d..1976ecad2 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -1,17 +1,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx'; +import { IReactionDisposer, action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { SnappingManager } from '../../../util/SnappingManager'; -import './DocCreatorMenu.scss'; -import { ObservableReactComponent } from '../../ObservableReactComponent'; -import { IconButton, Size } from 'browndash-components'; import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; +import { Doc } from '../../../../fields/Doc'; +import { DocCast, ImageCast } from '../../../../fields/Types'; +import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; +import { SnappingManager } from '../../../util/SnappingManager'; import { undoable } from '../../../util/UndoManager'; -import { DragManager } from '../../../util/DragManager'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../DocumentView'; -import { dropActionType } from '../../../util/DropActionTypes'; +import { DataVizBox } from './DataVizBox'; +import './DocCreatorMenu.scss'; @observer export class DocCreatorMenu extends ObservableReactComponent<{}> { @@ -20,22 +21,21 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { private _ref: HTMLDivElement | null = null; - private _reactionDisposer?: IReactionDisposer; + @observable _templateDocs: Doc[] = []; + @observable _icons : (ImageField|undefined)[] = []; @observable _pageX: number = 0; @observable _pageY: number = 0; @observable _display: boolean = false; - @observable _yRelativeToTop: boolean = true; - @observable _selectedIndex = -1; - @observable _mouseX: number = -1; @observable _mouseY: number = -1; - @observable _startPos: {x: number, y: number} | undefined = undefined; + @observable _startPos?: {x: number, y: number}; @observable _shouldDisplay: boolean = false; @observable _menuContent: 'templates' | 'options' = 'templates'; @observable _dragging: boolean = false; + @observable _dataViz?: DataVizBox; constructor(props: any) { super(props); @@ -43,6 +43,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { DocCreatorMenu.Instance = this; } + @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz }; + @action setTemplateDocs = (docs: Doc[]) => { + this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc); + }; + @action onPointerDown = (e: PointerEvent) => { this._mouseX = e.clientX; @@ -59,22 +64,19 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } }; + _disposer: IReactionDisposer|undefined; componentDidMount() { document.addEventListener('pointerdown', this.onPointerDown, true); document.addEventListener('pointerup', this.onPointerUp); + this._disposer = reaction(() => this._templateDocs.slice(), + async(docs) => this._icons = (await Promise.all(docs.map(doc => this.getIcon(doc)))) + , {fireImmediately: true}); } componentWillUnmount() { + this._disposer?.(); document.removeEventListener('pointerdown', this.onPointerDown, true); document.removeEventListener('pointerup', this.onPointerUp); - this._reactionDisposer?.(); - } - - static readonly buffer = 20; - static readonly width = 300; - static readonly height = 400; - get pageX() { - return this._pageX + DocCreatorMenu.width > window.innerWidth - DocCreatorMenu.buffer ? window.innerWidth - DocCreatorMenu.buffer - DocCreatorMenu.width : Math.max(0, this._pageX); } @action @@ -105,23 +107,37 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + async getIcon(doc: Doc) { + const docView = DocumentView.getDocumentView(doc); + if (docView) { + docView.ComponentView?.updateIcon?.(); + return new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500)); + } + return undefined; + } + get templatesPreviewContents(){ - const tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; return ( -
- {tempArray.map(i => -
- -
)} +
+ {this._icons.filter(url => url).map(url => +
+ +
) + }
); } get optionsMenuContents(){ return ( -
+
+
Dropdown
+
+
Link 1
+
Link 1
+
Link 1
+
+
); } @@ -181,6 +197,9 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { > + -

{this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} -- cgit v1.2.3-70-g09d2 From 6e65af16347169a9932c9e8ba737a2c76e684c5f Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 11 Jul 2024 01:53:02 -0400 Subject: menu --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 33 +++++++++++--- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 53 +++++++++++++++------- 2 files changed, 63 insertions(+), 23 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 43d4ed7e5..452d9b354 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -49,6 +49,8 @@ .docCreatorMenu-preview-container { display: grid; grid-template-columns: repeat(2, 1fr); + grid-template-rows: 140px; + grid-auto-rows: 141px; overflow-y: scroll; margin: 5px; width: calc(100% - 10px); @@ -57,17 +59,33 @@ border-radius: 5px; .docCreatorMenu-preview-window { + display: flex; + justify-content: center; + align-items: center; width: 125px; height: 125px; margin-top: 10px; margin-left: 10px; border: 1px solid whitesmoke; border-radius: 5px; + box-shadow: 5px 5px rgb(34, 34, 37); + + &:hover{ + background-color: rgb(72, 72, 73); + } + + .docCreatorMenu-preview-image{ + width: 105px; + height: 105px; + border-radius: 5px; + } + } } .docCreatorMenu-options-container { display: flex; + justify-content: center; overflow-y: scroll; margin: 5px; width: calc(100% - 10px); @@ -77,22 +95,23 @@ .docCreatorMenu-dropdown-button{ display: flex; - width: 120px; - height: 30px; + width: 140px; + height: 25px; background: whitesmoke; background-color: rgb(34, 34, 37); border-radius: 5px; border: 1px solid whitesmoke; padding: 0px; - font-size: 13px; + font-size: 12px; margin: 10px; - align-content: center; + align-items: center; justify-content: center; text-transform: uppercase; + cursor: pointer; - // &:hover .docCreatorMenu-dropdown-content{ - // display: block; - // } + &:hover .docCreatorMenu-dropdown-content{ + display: block; + } } .docCreatorMenu-dropdown-content { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 1976ecad2..7859ec60a 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IReactionDisposer, action, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; @@ -13,6 +13,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../DocumentView'; import { DataVizBox } from './DataVizBox'; import './DocCreatorMenu.scss'; +import { Id } from '../../../../fields/FieldSymbols'; +import { Colors } from 'browndash-components'; @observer export class DocCreatorMenu extends ObservableReactComponent<{}> { @@ -22,7 +24,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { private _ref: HTMLDivElement | null = null; @observable _templateDocs: Doc[] = []; - @observable _icons : (ImageField|undefined)[] = []; + @observable _templateRefToDoc?: ObservableMap; + @observable _selectedTemplateID?: Doc; @observable _pageX: number = 0; @observable _pageY: number = 0; @@ -64,13 +67,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } }; - _disposer: IReactionDisposer|undefined; + _disposer: IReactionDisposer | undefined; componentDidMount() { document.addEventListener('pointerdown', this.onPointerDown, true); document.addEventListener('pointerup', this.onPointerUp); - this._disposer = reaction(() => this._templateDocs.slice(), - async(docs) => this._icons = (await Promise.all(docs.map(doc => this.getIcon(doc)))) - , {fireImmediately: true}); + this._disposer = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon)); } componentWillUnmount() { @@ -117,13 +118,34 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } get templatesPreviewContents(){ + const renderedTemplates: Doc[] = []; return (
- {this._icons.filter(url => url).map(url => -
- -
) - } + {this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { + if (renderedTemplates.includes(info.doc)) return undefined; + renderedTemplates.push(info.doc); + return (
+ setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + this._selectedTemplateID = info.doc; + this.forceUpdate(); + }, 'open actions menu') + ) + }> + +
+ )})}
); } @@ -131,7 +153,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { get optionsMenuContents(){ return (
-
Dropdown
+
Choose Layout
Link 1
Link 1
@@ -173,9 +195,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); - }, 'open actions menu') + }, 'drag menu') ) - } onPointerMove={e => this.onPointerMove(e)} onPointerUp={() => this._dragging = false} @@ -191,7 +212,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { undoable(clickEv => { clickEv.stopPropagation(); runInAction(() => this._menuContent = this._menuContent === 'templates' ? 'options' : 'templates'); - }, 'open actions menu') + }, 'create docs') ) } > @@ -211,7 +232,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { undoable(clickEv => { clickEv.stopPropagation(); this.closeMenu(); - }, 'open actions menu') + }, 'close menu') ) } > -- cgit v1.2.3-70-g09d2 From 31bfb5e8b5e40322572252e1d823aebe48b27788 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 11 Jul 2024 02:54:35 -0400 Subject: menu --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 86 +++++++++++++++------- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 43 ++++++++--- 2 files changed, 93 insertions(+), 36 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 452d9b354..ba20c9179 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -85,7 +85,9 @@ .docCreatorMenu-options-container { display: flex; - justify-content: center; + flex-direction: column; + justify-content: flex-start; + align-items: center; overflow-y: scroll; margin: 5px; width: calc(100% - 10px); @@ -93,40 +95,72 @@ border: 1px solid whitesmoke; border-radius: 5px; - .docCreatorMenu-dropdown-button{ - display: flex; + .docCreatorMenu-dropdown-hoverable { width: 140px; height: 25px; - background: whitesmoke; - background-color: rgb(34, 34, 37); - border-radius: 5px; - border: 1px solid whitesmoke; - padding: 0px; - font-size: 12px; - margin: 10px; - align-items: center; - justify-content: center; - text-transform: uppercase; - cursor: pointer; + margin-bottom: 17px; + z-index: 5; - &:hover .docCreatorMenu-dropdown-content{ + &:hover .docCreatorMenu-dropdown-content { display: block; } - } - - .docCreatorMenu-dropdown-content { - display: none; - position: absolute; - min-width: 100px; - z-index: 1; - .docCreatorMenu-dropdown-option{ - display: block; + &:hover .docCreatorMenu-dropdown-title { + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; } + .docCreatorMenu-dropdown-title{ + display: flex; + width: 140px; + height: 25px; + background: whitesmoke; + background-color: rgb(34, 34, 37); + border-radius: 5px; + border: 1px solid whitesmoke; + padding: 0px; + font-size: 12px; + margin-top: 10px; + align-items: center; + justify-content: center; + text-transform: uppercase; + cursor: pointer; + } + + .docCreatorMenu-dropdown-content { + display: none; + min-width: 100px; + height: 75px; + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; + + .docCreatorMenu-dropdown-option{ + display: flex; + background-color: rgb(42, 42, 46); + border-left: 1px solid whitesmoke; + border-right: 1px solid whitesmoke; + border-bottom: 1px solid whitesmoke; + width: 140px; + height: 25px; + justify-content: center; + justify-items: center; + padding-top: 3px; + + &:hover { + background-color: rgb(68, 68, 74); + cursor: pointer; + } + } + } } - - + .docCreatorMenu-layout-preview-window { + width: 85%; + height: 100px; + border: 1px solid whitesmoke; + border-radius: 5px; + background-color: rgb(34, 34, 37); + } } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 7859ec60a..356172b6a 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -27,6 +27,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplateID?: Doc; + @observable _selectedLayout?: 'stacked' | 'grid' | 'row' | 'column' | 'custom'; + @observable _pageX: number = 0; @observable _pageY: number = 0; @observable _display: boolean = false; @@ -131,11 +133,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { boxShadow: this._selectedTemplateID === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} onPointerDown={e => - setupMoveUpEvents( - this, - e, - returnFalse, - emptyFunction, + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); this._selectedTemplateID = info.doc; @@ -151,13 +149,38 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } get optionsMenuContents(){ + + const layoutOption = (option: 'stacked' | 'grid' | 'row' | 'column' | 'custom') => { + return ( +
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + runInAction(() => this._selectedLayout = option); + }, 'open actions menu') + ) + }> + {option} +
+ ); + } + return (
-
Choose Layout
-
-
Link 1
-
Link 1
-
Link 1
+
+
Choose Layout
+
+ {layoutOption('stacked')} + {layoutOption('grid')} + {layoutOption('row')} + {layoutOption('column')} + {layoutOption('custom')} +
+
+
+
); -- cgit v1.2.3-70-g09d2 From 54fbd0815e93da8aff7a601676a90aa0faf87de8 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:19:04 -0400 Subject: collection filtering works --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 5 ++--- src/client/views/nodes/DataVizBox/DocCreatorMenu.scss | 5 +++-- src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index f75ba9700..c43177c51 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -457,10 +457,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { getPossibleTemplates = (): Doc[] => { const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(this.Document).map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document))); - const linkedCollections: Doc[] = linkedDocs.filter(doc => doc.type === 'config').filter(doc => DocCast(doc.annotationOn).type === 'collection'); + const linkedCollections: Doc[] = linkedDocs.filter(doc => doc.type === 'config').filter(doc => DocCast(doc.annotationOn).type === 'collection').map(doc => DocCast(doc.annotationOn)); const isColumnTitle = (title: string): boolean => { const colTitles: string[] = Object.keys(this.records[0]); - console.log('titles: ' + colTitles) for (let i = 0; i < colTitles.length; ++i){ if (colTitles[i] === title) { console.log(true); @@ -477,7 +476,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { } return false; } - return linkedDocs; + return linkedCollections.filter(col => isValidTemplate(col)); } /** diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index ba20c9179..4944f3071 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -66,9 +66,9 @@ height: 125px; margin-top: 10px; margin-left: 10px; - border: 1px solid whitesmoke; + border: 1px solid rgb(163, 163, 163); border-radius: 5px; - box-shadow: 5px 5px rgb(34, 34, 37); + box-shadow: 5px 5px rgb(29, 29, 31); &:hover{ background-color: rgb(72, 72, 73); @@ -134,6 +134,7 @@ overflow-y: scroll; -ms-overflow-style: none; scrollbar-width: none; + border-bottom: solid 1px whitesmoke; .docCreatorMenu-dropdown-option{ display: flex; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 356172b6a..3ebf97570 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -150,10 +150,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { get optionsMenuContents(){ - const layoutOption = (option: 'stacked' | 'grid' | 'row' | 'column' | 'custom') => { + const layoutOption = (option: 'stacked' | 'grid' | 'row' | 'column' | 'custom', optStyle?: {}) => { return (
setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoable(clickEv => { @@ -176,7 +177,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { {layoutOption('grid')} {layoutOption('row')} {layoutOption('column')} - {layoutOption('custom')} + {layoutOption('custom', {borderBottom: `0px`})}
@@ -239,7 +240,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { ) } > - +
-
- + {this._layoutPreview ? this.layoutPreviewContents : null} +
+
Repeat
+
); @@ -253,7 +290,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { ) } > - +
+ {this._selectedLayout ? this.layoutConfigOptions: null} {this._layoutPreview ? this.layoutPreviewContents : null} -
-
Repeat
- -
+ {selectionBox(100, 30, 'Repeat:', undefined, repeatOptions.map(num => ))}
); } -- cgit v1.2.3-70-g09d2 From e0dbe3a59d2e1e61fda951c250ef8d43cc0ccd3d Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 15 Jul 2024 01:38:38 -0400 Subject: layout options/preview progress --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 14 ++ .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 250 +++++++++++++-------- 2 files changed, 174 insertions(+), 90 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 71ad9e105..e3530c0ef 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -271,12 +271,26 @@ } .docCreatorMenu-layout-preview-window { + padding: 5px; + overflow: scroll; aspect-ratio: 1 / 1; + display: grid; width: 85%; border: 1px solid whitesmoke; border-radius: 5px; background-color: rgb(34, 34, 37); margin-top: 10px; + -ms-overflow-style: none; + scrollbar-width: none; + + .docCreatorMenu-layout-preview-item { + display: flex; + justify-content: center; + align-items: center; + border-radius: 3px; + border: solid 1px lightblue; + } } } + diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index a45234a79..c8b414c59 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -1,9 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IReactionDisposer, ObservableMap, action, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { returnAll, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; -import { Doc } from '../../../../fields/Doc'; +import { Doc, NumListCast } from '../../../../fields/Doc'; import { DocCast, ImageCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; @@ -16,6 +16,7 @@ import './DocCreatorMenu.scss'; import { Id } from '../../../../fields/FieldSymbols'; import { Colors } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; +import { threadId } from 'worker_threads'; export enum LayoutType { Stacked = 'stacked', @@ -37,7 +38,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplate: Doc | undefined = undefined; - @observable _selectedLayout: LayoutType | undefined = undefined; + @observable _layout: {type?: LayoutType, yMargin: number, xMargin: number, rows?:number, columns?: number} = {yMargin: 0, xMargin: 0}; @observable _layoutPreview: boolean = false; @observable _pageX: number = 0; @@ -62,6 +63,35 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz }; @action setTemplateDocs = (docs: Doc[]) => {this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc)}; + @computed get docsToRender() { + return NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows); + } + + @computed get rowsCount(){ + switch (this._layout.type) { + case LayoutType.Row: case LayoutType.Stacked: + return 1; + case LayoutType.Column: + return this.docsToRender.length; + case LayoutType.Grid: + return this._layout.rows ?? 0; + default: + return 0; + } + } + + @computed get columnsCount(){ + switch (this._layout.type) { + case LayoutType.Row: + return this.docsToRender.length; + case LayoutType.Column: case LayoutType.Stacked: + return 1; + case LayoutType.Grid: + return this._layout.columns ?? 0; + default: + return 0; + } + } @action onPointerDown = (e: PointerEvent) => { @@ -158,40 +188,50 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { ); } + @action updateXMargin = (input: string) => { this._layout.xMargin = Number(input) }; + @action updateYMargin = (input: string) => { this._layout.yMargin = Number(input) }; + @action updateDimensions = (dimension: 'x' | 'y', input: string) => { + if (dimension === 'x') { + this._layout.rows = Number(input); + } else { + this._layout.columns = Number(input); + } + }; + get layoutConfigOptions() { - const optionInput = (title: string) => { + const optionInput = (title: string, func: Function) => { return (
{title}
- + func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/>
); } - switch (this._selectedLayout) { + switch (this._layout.type) { case LayoutType.Row: case LayoutType.Column: return (
- {optionInput('Y Margin:')} - {optionInput('X Margin:')} + {optionInput('Y Margin:', this.updateYMargin)} + {optionInput('X Margin:', this.updateXMargin)}
); case LayoutType.Grid: return ( <>
- {optionInput('Y Margin:')} - {optionInput('X Margin:')} + {optionInput('Y Margin:', this.updateYMargin)} + {optionInput('X Margin:', this.updateXMargin)}
Dimensions:
- + {this.updateDimensions('x', e.currentTarget.value); this.forceUpdate()}}/>
x
- + this.updateDimensions('y', e.currentTarget.value)}/>
); @@ -203,8 +243,38 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } get layoutPreviewContents() { + const docWidth = Number(this._selectedTemplate?._width); + const docHeight = Number(this._selectedTemplate?._height); + const horizontalSpan: number = (docWidth + this._layout.xMargin) * this.columnsCount - this._layout.xMargin; + const verticalSpan: number = (docHeight + this._layout.yMargin) * this.rowsCount - this._layout.yMargin; + const largerSpan: number = horizontalSpan > verticalSpan ? horizontalSpan : verticalSpan; + const scaleDownFactor: number = largerSpan / 235; + const scaledWidth = docWidth / scaleDownFactor; + const scaledHeight = docHeight / scaleDownFactor; + + console.log(this.rowsCount); + console.log(this.columnsCount) + return ( -
+
+ {this.docsToRender.map(num => +
+ {num} +
+ )}
); @@ -220,7 +290,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); - runInAction(() => this._selectedLayout = option); + runInAction(() => this._layout.type = option); }, 'open actions menu') ) }> @@ -248,7 +318,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
-
{this._selectedLayout ? this._selectedLayout.toUpperCase() : 'Choose Layout'}
+
{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}
{layoutOption(LayoutType.Stacked)} {layoutOption(LayoutType.Grid)} @@ -270,7 +340,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
- {this._selectedLayout ? this.layoutConfigOptions: null} + {this._layout.type ? this.layoutConfigOptions: null} {this._layoutPreview ? this.layoutPreviewContents : null} {selectionBox(100, 30, 'Repeat:', undefined, repeatOptions.map(num => ))}
@@ -279,79 +349,61 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { render() { return ( -
this._ref = r} - style={{ - display: '', - left: this._pageX, - top: this._pageY, - width: this._shouldDisplay ? 300 : 0, - height: this._shouldDisplay ? 400 : 0, - background: SnappingManager.userBackgroundColor, - color: SnappingManager.userColor, - }}> - {!this._shouldDisplay ? undefined : - <> -
- setupMoveUpEvents( - this, - e, - (e) => { - this._dragging = true; - this._startPos = {x: 0, y: 0}; - this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0); - this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0); - return true; - }, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - }, 'drag menu') - ) - } - onPointerMove={e => this.onPointerMove(e)} - onPointerUp={() => this._dragging = false} - > - - - + -
-
- {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} - - } + + + +
+
+ {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} +
+ }
) } -- cgit v1.2.3-70-g09d2 From f992fbeed6c523985e5ee6c851217a0dc38358d4 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:42:08 -0400 Subject: working on layout preview window --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 7 ++- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 63 +++++++++++----------- 2 files changed, 33 insertions(+), 37 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index e3530c0ef..bfc1c1216 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -211,7 +211,6 @@ .docCreatorMenu-menu-container { display: flex; flex-direction: column; - justify-content: flex-start; align-items: center; overflow-y: scroll; margin: 5px; @@ -272,14 +271,14 @@ .docCreatorMenu-layout-preview-window { padding: 5px; + flex: 0 0 auto; overflow: scroll; - aspect-ratio: 1 / 1; display: grid; - width: 85%; + width: 240; + height: 240; border: 1px solid whitesmoke; border-radius: 5px; background-color: rgb(34, 34, 37); - margin-top: 10px; -ms-overflow-style: none; scrollbar-width: none; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index c8b414c59..9da9f5aa8 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -17,6 +17,7 @@ import { Id } from '../../../../fields/FieldSymbols'; import { Colors } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; import { threadId } from 'worker_threads'; +import { ideahub } from 'googleapis/build/src/apis/ideahub'; export enum LayoutType { Stacked = 'stacked', @@ -40,6 +41,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _layout: {type?: LayoutType, yMargin: number, xMargin: number, rows?:number, columns?: number} = {yMargin: 0, xMargin: 0}; @observable _layoutPreview: boolean = false; + @observable _layoutPreviewScale: number = 1; @observable _pageX: number = 0; @observable _pageY: number = 0; @@ -190,48 +192,42 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action updateXMargin = (input: string) => { this._layout.xMargin = Number(input) }; @action updateYMargin = (input: string) => { this._layout.yMargin = Number(input) }; - @action updateDimensions = (dimension: 'x' | 'y', input: string) => { - if (dimension === 'x') { - this._layout.rows = Number(input); - } else { - this._layout.columns = Number(input); - } - }; + @action updateColumns = (input: string) => { this._layout.columns = Number(input) }; get layoutConfigOptions() { - const optionInput = (title: string, func: Function) => { + const optionInput = (title: string, func: Function, def?: number, key?: string) => { return ( -
+
{title}
- func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/> + func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/>
); } switch (this._layout.type) { - case LayoutType.Row: case LayoutType.Column: + case LayoutType.Row: + return ( +
+ {optionInput('Margin:', this.updateXMargin, this._layout.xMargin, '0')} +
+ ); + case LayoutType.Column: return (
- {optionInput('Y Margin:', this.updateYMargin)} - {optionInput('X Margin:', this.updateXMargin)} + {optionInput('Margin:', this.updateYMargin, this._layout.yMargin, '1')}
); case LayoutType.Grid: return ( <>
- {optionInput('Y Margin:', this.updateYMargin)} - {optionInput('X Margin:', this.updateXMargin)} + {optionInput('Y Margin:', this.updateYMargin, this._layout.xMargin, '2')} + {optionInput('X Margin:', this.updateXMargin, this._layout.xMargin, '3')}
-
- Dimensions: -
- {this.updateDimensions('x', e.currentTarget.value); this.forceUpdate()}}/> -
x
- this.updateDimensions('y', e.currentTarget.value)}/> + {optionInput('Columns:', this.updateColumns, this._layout.columns, '3')}
); @@ -248,28 +244,29 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const horizontalSpan: number = (docWidth + this._layout.xMargin) * this.columnsCount - this._layout.xMargin; const verticalSpan: number = (docHeight + this._layout.yMargin) * this.rowsCount - this._layout.yMargin; const largerSpan: number = horizontalSpan > verticalSpan ? horizontalSpan : verticalSpan; - const scaleDownFactor: number = largerSpan / 235; - const scaledWidth = docWidth / scaleDownFactor; - const scaledHeight = docHeight / scaleDownFactor; - - console.log(this.rowsCount); - console.log(this.columnsCount) + const scaledDown = (input: number) => {return input / (largerSpan / 225 * this._layoutPreviewScale)} + const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3)); return (
+ {/* */} {this.docsToRender.map(num =>
{num} -- cgit v1.2.3-70-g09d2 From bcbbfc670b95530b4dd9bd258e726fe75c47cfa8 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 16 Jul 2024 03:17:11 -0400 Subject: refactored click events; zoom in/out option --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 82 ++++++++--- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 150 +++++++++------------ 2 files changed, 125 insertions(+), 107 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index bfc1c1216..a9b4e2501 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -1,3 +1,10 @@ +.no-margin { + margin-top: 0px !important; + margin-bottom: 0px !important; + margin-left: 0px !important; + margin-right: 0px !important; +} + .docCreatorMenu-cont { position: absolute; z-index: 100000; @@ -269,25 +276,64 @@ } - .docCreatorMenu-layout-preview-window { - padding: 5px; - flex: 0 0 auto; - overflow: scroll; - display: grid; - width: 240; - height: 240; - border: 1px solid whitesmoke; - border-radius: 5px; - background-color: rgb(34, 34, 37); - -ms-overflow-style: none; - scrollbar-width: none; - - .docCreatorMenu-layout-preview-item { - display: flex; - justify-content: center; - align-items: center; + .docCreatorMenu-layout-preview-window-wrapper { + display: flex; + justify-content: center; + align-items: center; + width: 85%; + height: auto; + position: relative; + padding: 0px; + + &:hover .docCreatorMenu-zoom-button { + display: block; + } + + .docCreatorMenu-layout-preview-window { + padding: 5px; + flex: 0 0 auto; + overflow: scroll; + display: grid; + width: auto; + height: auto; + max-width: 240; + max-height: 240; + border: 1px solid whitesmoke; + border-radius: 5px; + background-color: rgb(34, 34, 37); + -ms-overflow-style: none; + scrollbar-width: none; + + .docCreatorMenu-layout-preview-item { + display: flex; + justify-content: center; + align-items: center; + border-radius: 3px; + border: solid 1px lightblue; + } + } + + .docCreatorMenu-zoom-button{ + display: none; + width: 15px; + height: 15px; + background: whitesmoke; + background-color: rgb(34, 34, 37); border-radius: 3px; - border: solid 1px lightblue; + border: 1px solid whitesmoke; + padding: 0px; + font-size: 10px; + position: absolute; + top: 0px; + z-index: 6; + margin-left: 0px; + margin-top: 0px; + margin-right: 225px; + margin-bottom: 0px; + + &.zoom-in{ + top: 15px; + } } } } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 9da9f5aa8..bae2d2000 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -39,7 +39,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplate: Doc | undefined = undefined; - @observable _layout: {type?: LayoutType, yMargin: number, xMargin: number, rows?:number, columns?: number} = {yMargin: 0, xMargin: 0}; + @observable _layout: {type?: LayoutType, yMargin: number, xMargin: number, rows?:number, columns: number} = {yMargin: 0, xMargin: 0, columns: 1}; @observable _layoutPreview: boolean = false; @observable _layoutPreviewScale: number = 1; @@ -76,7 +76,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { case LayoutType.Column: return this.docsToRender.length; case LayoutType.Grid: - return this._layout.rows ?? 0; + return Math.ceil(this.docsToRender.length / (this._layout.columns ?? 1)) ?? 0; default: return 0; } @@ -95,6 +95,19 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + setUpButtonClick = (e: any, func: Function) => { + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + func(); + }, 'create docs') + ) + } + @action onPointerDown = (e: PointerEvent) => { this._mouseX = e.clientX; @@ -130,7 +143,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { this._shouldDisplay = false; } else { this._pageX = x; - console.log(y); this._pageY = y; this._shouldDisplay = true; } @@ -174,15 +186,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { background: this._selectedTemplate === info.doc ? Colors.MEDIUM_BLUE : '', boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} - onPointerDown={e => - setupMoveUpEvents(this, e, returnFalse, emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - this._selectedTemplate = info.doc; - MakeTemplate(info.doc); - }, 'open actions menu') - ) - }> + onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => {this._selectedTemplate = info.doc; MakeTemplate(info.doc);}))}>
)})} @@ -195,9 +199,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action updateColumns = (input: string) => { this._layout.columns = Number(input) }; get layoutConfigOptions() { - const optionInput = (title: string, func: Function, def?: number, key?: string) => { + const optionInput = (title: string, func: Function, def?: number, key?: string, noMargin?: boolean) => { return ( -
+
{title}
@@ -226,8 +231,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { {optionInput('Y Margin:', this.updateYMargin, this._layout.xMargin, '2')} {optionInput('X Margin:', this.updateXMargin, this._layout.xMargin, '3')}
-
- {optionInput('Columns:', this.updateColumns, this._layout.columns, '3')} +
+ {optionInput('Columns:', this.updateColumns, this._layout.columns, '3', true)}
); @@ -248,49 +253,51 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3)); return ( -
- {/* */} - {this.docsToRender.map(num => -
- {num} -
- )} +
+ + +
+ {this.docsToRender.map(num => +
+ {num} +
+ )} +
); } get optionsMenuContents(){ - const layoutOption = (option: LayoutType, optStyle?: {}) => { + const layoutOption = (option: LayoutType, optStyle?: {}, specialFunc?: Function) => { return (
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - runInAction(() => this._layout.type = option); - }, 'open actions menu') - ) - }> + onPointerDown={e => this.setUpButtonClick(e, () => {specialFunc?.(); runInAction(() => this._layout.type = option)})}> {option}
); @@ -318,7 +325,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}
{layoutOption(LayoutType.Stacked)} - {layoutOption(LayoutType.Grid)} + {layoutOption(LayoutType.Grid, undefined, () => {this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length))})} {layoutOption(LayoutType.Row)} {layoutOption(LayoutType.Column)} {layoutOption(LayoutType.Custom, {borderBottom: `0px`})} @@ -326,14 +333,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
@@ -384,29 +384,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { >
-- cgit v1.2.3-70-g09d2 From dcbc6f5657109b19b623f946a1e86e1940a5c60c Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:10:05 -0400 Subject: work on menu (mostly UI improvements) --- src/client/views/MainView.tsx | 3 + .../views/nodes/DataVizBox/DocCreatorMenu.scss | 37 +++++++----- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 68 +++++++++++++--------- 3 files changed, 68 insertions(+), 40 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 926e5fd55..d337aae68 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -279,6 +279,9 @@ export class MainView extends ObservableReactComponent<{}> { library.add( ...[ + fa.faRepeat, + fa.faArrowsUpDown, + fa.faArrowsLeftRight, fa.faWindowMaximize, fa.faGift, fa.faLockOpen, diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index a9b4e2501..d2f8f13d1 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -25,9 +25,14 @@ background: whitesmoke; background-color: rgb(34, 34, 37); border-radius: 5px; - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); padding: 0px; font-size: 14px; + //box-shadow: 3px 3px rgb(29, 29, 31); + + &:hover { + box-shadow: none; + } &.right{ margin-left: 0px; @@ -51,6 +56,7 @@ .docCreatorMenu-menu-hr{ margin-top: 0px; margin-bottom: 0px; + color: rgb(180, 180, 180); } //------------------------------------------------------------------------------------------------------------------------------------------ @@ -67,7 +73,7 @@ margin: 5px; width: calc(100% - 10px); height: calc(100% - 51px); - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); border-radius: 5px; .docCreatorMenu-preview-window { @@ -107,6 +113,7 @@ justify-content: center; align-items: center; margin-top: 10px; + margin-bottom: 10px; &.layout{ z-index: 5; @@ -120,7 +127,7 @@ background: whitesmoke; background-color: rgb(34, 34, 37); border-radius: 5px; - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); padding: 0px; font-size: 12px; align-items: center; @@ -142,10 +149,12 @@ } &.config { + border-radius: 4px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; - width: 60px; + width: 30px; border-right: 0px; + gap: 3px; &.layout-config { height: 20px; @@ -167,17 +176,17 @@ display: flex; height: 30px; background-color: rgb(34, 34, 37); - border-radius: 5px; - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); align-items: center; justify-content: center; &.config { + border-radius: 4px; margin: 0px; border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left: 0px; - width: 40px; + width: 25px; &.layout-config { height: 20px; @@ -223,7 +232,7 @@ margin: 5px; width: calc(100% - 10px); height: calc(100% - 51px); - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); border-radius: 5px; .docCreatorMenu-option-container{ @@ -250,16 +259,16 @@ overflow-y: scroll; -ms-overflow-style: none; scrollbar-width: none; - border-bottom: solid 1px whitesmoke; + border-bottom: 1px solid rgb(180, 180, 180); border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; .docCreatorMenu-dropdown-option{ display: flex; background-color: rgb(42, 42, 46); - border-left: 1px solid whitesmoke; - border-right: 1px solid whitesmoke; - border-bottom: 1px solid whitesmoke; + border-left: 1px solid rgb(180, 180, 180); + border-right: 1px solid rgb(180, 180, 180); + border-bottom: 1px solid rgb(180, 180, 180); width: 140px; height: 25px; justify-content: center; @@ -298,7 +307,7 @@ height: auto; max-width: 240; max-height: 240; - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); border-radius: 5px; background-color: rgb(34, 34, 37); -ms-overflow-style: none; @@ -320,7 +329,7 @@ background: whitesmoke; background-color: rgb(34, 34, 37); border-radius: 3px; - border: 1px solid whitesmoke; + border: 1px solid rgb(180, 180, 180); padding: 0px; font-size: 10px; position: absolute; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index bae2d2000..3eda2c891 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -14,7 +14,7 @@ import { DocumentView } from '../DocumentView'; import { DataVizBox } from './DataVizBox'; import './DocCreatorMenu.scss'; import { Id } from '../../../../fields/FieldSymbols'; -import { Colors } from 'browndash-components'; +import { Colors, IconButton, Size } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; import { threadId } from 'worker_threads'; import { ideahub } from 'googleapis/build/src/apis/ideahub'; @@ -39,8 +39,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplate: Doc | undefined = undefined; - @observable _layout: {type?: LayoutType, yMargin: number, xMargin: number, rows?:number, columns: number} = {yMargin: 0, xMargin: 0, columns: 1}; - @observable _layoutPreview: boolean = false; + @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, columns: 1}; + @observable _layoutPreview: boolean = true; @observable _layoutPreviewScale: number = 1; @observable _pageX: number = 0; @@ -173,6 +173,16 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return undefined; } + @action updateSelectedTemplate = (template: Doc) => { + if (this._selectedTemplate === template) { + this._selectedTemplate = undefined; + return; + } else { + this._selectedTemplate = template; + MakeTemplate(template); + } + } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; return ( @@ -186,7 +196,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { background: this._selectedTemplate === info.doc ? Colors.MEDIUM_BLUE : '', boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} - onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => {this._selectedTemplate = info.doc; MakeTemplate(info.doc);}))}> + onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
)})} @@ -199,12 +209,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action updateColumns = (input: string) => { this._layout.columns = Number(input) }; get layoutConfigOptions() { - const optionInput = (title: string, func: Function, def?: number, key?: string, noMargin?: boolean) => { + const optionInput = (icon: string, func: Function, def?: number, key?: string, noMargin?: boolean) => { return ( -
- {title} +
func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/>
@@ -215,26 +225,22 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { case LayoutType.Row: return (
- {optionInput('Margin:', this.updateXMargin, this._layout.xMargin, '0')} + {optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '0')}
); case LayoutType.Column: return (
- {optionInput('Margin:', this.updateYMargin, this._layout.yMargin, '1')} + {optionInput('arrows-up-down', this.updateYMargin, this._layout.yMargin, '1')}
); case LayoutType.Grid: return ( - <>
- {optionInput('Y Margin:', this.updateYMargin, this._layout.xMargin, '2')} - {optionInput('X Margin:', this.updateXMargin, this._layout.xMargin, '3')} + {optionInput('arrows-up-down', this.updateYMargin, this._layout.xMargin, '2')} + {optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '3')} + {optionInput('table-columns', this.updateColumns, this._layout.columns, '4', true)}
-
- {optionInput('Columns:', this.updateColumns, this._layout.columns, '3', true)} -
- ); case LayoutType.Stacked: return null; @@ -273,7 +279,18 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { rowGap: `${scaledDown(this._layout.yMargin)}px`, columnGap: `${scaledDown(this._layout.xMargin)}px` }}> - {this.docsToRender.map(num => + {this._layout.type === LayoutType.Stacked ? +
+ All +
: + this.docsToRender.map(num =>
{ ); } - const selectionBox = (width: number, height: number, title: string, specClass?: string, options?: JSX.Element[], manual?: boolean): JSX.Element => { + const selectionBox = (width: number, height: number, icon: string, specClass?: string, options?: JSX.Element[], manual?: boolean): JSX.Element => { return (
-
- {title} +
+
- {manual ? : - : + } @@ -339,7 +356,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._layout.type ? this.layoutConfigOptions: null} {this._layoutPreview ? this.layoutPreviewContents : null} - {selectionBox(100, 30, 'Repeat:', undefined, repeatOptions.map(num => ))} + {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))}
); } @@ -381,7 +398,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } onPointerMove={e => this.onPointerMove(e)} onPointerUp={() => this._dragging = false} - > + >
-
{this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents}
} @@ -417,6 +433,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { export interface DataVizTemplateInfo { doc?: Doc; - layout?: LayoutType; + layout?: {}; repeat?: number; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 58d3eeb6e45555e5eeaf172f571b500ca3b564c0 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 17 Jul 2024 00:54:22 -0400 Subject: creation with layout works --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 38 ++++++++++++++++- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 10 +++++ .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 48 ++++++++++++++++++---- 3 files changed, 88 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 283288013..e03da8e7b 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -33,10 +33,11 @@ import { LineChart } from './components/LineChart'; import { PieChart } from './components/PieChart'; import { TableBox } from './components/TableBox'; import { LinkManager } from '../../../util/LinkManager'; -import { DataVizTemplateInfo, DocCreatorMenu } from './DocCreatorMenu'; +import { DataVizTemplateInfo, DocCreatorMenu, LayoutType } from './DocCreatorMenu'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { PrefetchProxy } from '../../../../fields/Proxy'; import { AclAdmin, AclAugment, AclEdit } from '../../../../fields/DocSymbols'; +import { template } from 'lodash'; export enum DataVizView { TABLE = 'table', @@ -494,6 +495,38 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { return target; } + applyLayout = (templateInfo: DataVizTemplateInfo, docs: Doc[]) => { + if (templateInfo.layout.type === LayoutType.Stacked) return; + const columns: number = templateInfo.columns; + const xGap: number = templateInfo.layout.xMargin; + const yGap: number = templateInfo.layout.yMargin; + const repeat: number = templateInfo.layout.repeat; + const startX: number = templateInfo.referencePos.x; + const startY: number = templateInfo.referencePos.y; + const templWidth = Number(templateInfo.doc._width); + const templHeight = Number(templateInfo.doc._height); + + let i: number = 0; + let docsChanged: number = 0; + let curX: number = startX; + let curY: number = startY; + + while (docsChanged < docs.length){ + while (i < columns && docsChanged < docs.length){ + docs[docsChanged].x = curX; + docs[docsChanged].y = curY; + console.log('x: ' + docs[i].x + ' y: ' + docs[i].y); + curX += templWidth + xGap; + ++docsChanged; + ++i; + } + + i = 0; + curX = startX; + curY += templHeight + yGap; + } + } + @action createDocsFromTemplate = (templateInfo: DataVizTemplateInfo) => { if (!templateInfo.doc) return; @@ -514,7 +547,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { target.layout_fieldKey = targetKey; return applied; }); + docs.forEach(doc => mainCollection.addDocument(doc)); + + this.applyLayout(templateInfo, docs); } /** diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index d2f8f13d1..8b17f1ed4 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -59,6 +59,16 @@ color: rgb(180, 180, 180); } + +.docCreatorMenu-placement-indicator { + position: absolute; + z-index: 100000; + border-left: solid 3px #9fd7fb; + border-top: solid 3px #9fd7fb; + width: 25px; + height: 25px; +} + //------------------------------------------------------------------------------------------------------------------------------------------ //DocCreatorMenu templates preview CSS //-------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 3eda2c891..b1488679f 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -33,18 +33,19 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { static Instance: DocCreatorMenu; private _ref: HTMLDivElement | null = null; - private _templateInfo: DataVizTemplateInfo = {}; @observable _templateDocs: Doc[] = []; @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplate: Doc | undefined = undefined; - @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, columns: 1}; + @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns: number, repeat: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, columns: 1, repeat: 0}; @observable _layoutPreview: boolean = true; @observable _layoutPreviewScale: number = 1; @observable _pageX: number = 0; @observable _pageY: number = 0; + @observable _indicatorX: number | undefined = undefined; + @observable _indicatorY: number | undefined = undefined; @observable _display: boolean = false; @observable _mouseX: number = -1; @@ -54,6 +55,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _menuContent: 'templates' | 'options' = 'templates'; @observable _dragging: boolean = false; + @observable _draggingIndicator: boolean = false; @observable _dataViz?: DataVizBox; constructor(props: any) { @@ -158,6 +160,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action onPointerMove = (e: any) => { + // if (this._draggingIndicator) { + // this._indicatorX = e.pageX - (this._startPos?.x ?? 0) + this._pageX; + // this._indicatorY = e.pageY - (this._startPos?.y ?? 0) + this._pageY; + // } else if (this._dragging){ this._pageX = e.pageX - (this._startPos?.x ?? 0); this._pageY = e.pageY - (this._startPos?.y ?? 0); @@ -356,7 +362,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._layout.type ? this.layoutConfigOptions: null} {this._layoutPreview ? this.layoutPreviewContents : null} - {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))} + {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))}
); } @@ -365,6 +371,31 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return (
{!this._shouldDisplay ? undefined : + <> + {/*
this.onPointerMove(e)} + onPointerDown={e => + setupMoveUpEvents( + this, + e, + (e) => { + this._draggingIndicator = true; + this._startPos = {x: 0, y: 0}; + this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0); + this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0); + return true; + }, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + }, 'drag menu') + ) + }/> */}
this._ref = r} @@ -410,7 +441,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { undoable(clickEv => { clickEv.stopPropagation(); if (!this._selectedTemplate) return; - const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate}; + const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate, layout: this._layout, referencePos: {x: this._pageX + 450, y: this._pageY}, columns: this.columnsCount}; + this._dataViz?.createDocsFromTemplate(templateInfo); }, 'make docs') ) @@ -425,6 +457,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents}
+ }
) @@ -432,7 +465,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } export interface DataVizTemplateInfo { - doc?: Doc; - layout?: {}; - repeat?: number; + doc: Doc; + layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number}; + columns: number; + referencePos: {x: number, y: number}; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From ded7673796965e9cb9239cfd483a2f1e35abd38b Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:28:05 -0400 Subject: highlighting rows based on layoutpreview hover --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 20 ++++++++++++++++++-- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 11 +++++++++-- src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 18 +++++++++++++----- .../views/nodes/DataVizBox/components/TableBox.tsx | 6 ++++-- src/client/views/nodes/ImageBox.tsx | 2 +- 5 files changed, 45 insertions(+), 12 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index e03da8e7b..765642891 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -38,6 +38,7 @@ import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { PrefetchProxy } from '../../../../fields/Proxy'; import { AclAdmin, AclAugment, AclEdit } from '../../../../fields/DocSymbols'; import { template } from 'lodash'; +import { data } from 'jquery'; export enum DataVizView { TABLE = 'table', @@ -57,6 +58,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined; @observable _marqueeing: number[] | undefined = undefined; @observable _savedAnnotations = new ObservableMap(); + @observable _specialHighlightedRow: number | undefined = undefined; constructor(props: FieldViewProps) { super(props); @@ -131,6 +133,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { this.layoutDoc._dataViz_titleCol = titleCol; }; + @action setSpecialHighlightedRow = (row: number | undefined) => { + this._specialHighlightedRow = row; + } + @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors restoreView = (data: Doc) => { // const changedView = data.config_dataViz && this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz); @@ -366,7 +372,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { }; if (!this.records.length) return 'no data/visualization'; switch (this.dataVizView) { - case DataVizView.TABLE: return ; + case DataVizView.TABLE: return ; case DataVizView.LINECHART: return {this._vizRenderer = r ?? undefined;}} vizBox={this} />; case DataVizView.HISTOGRAM: return {this._vizRenderer = r ?? undefined;}} />; case DataVizView.PIECHART: return {this._vizRenderer = r ?? undefined;}} @@ -515,7 +521,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { while (i < columns && docsChanged < docs.length){ docs[docsChanged].x = curX; docs[docsChanged].y = curY; - console.log('x: ' + docs[i].x + ' y: ' + docs[i].y); curX += templWidth + xGap; ++docsChanged; ++i; @@ -527,6 +532,16 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { } } + // applyImagesTo = (doc: Doc, cols: string[]) => { + // const childDocs = DocListCast(doc[Doc.LayoutFieldKey(doc)]); + // const imageFields = childDocs.filter(doc => doc.type === 'image'); + // const imageToKey: Map = new Map(); + // imageFields.forEach(img => cols.forEach(col => {if (img[col]) imageToKey.set(img, col)})); + + // imageFields.forEach(doc => doc['data'] = String(doc[String(imageToKey.get(doc))]).replace(/"/g, '')); + + // } + @action createDocsFromTemplate = (templateInfo: DataVizTemplateInfo) => { if (!templateInfo.doc) return; @@ -545,6 +560,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { const targetKey = StrCast(templateInfo.doc!.layout_fieldKey, 'layout'); const applied = this.ApplyTemplateTo(templateInfo.doc!, target, targetKey, templateInfo.doc!.title + `${row}`); target.layout_fieldKey = targetKey; + //this.applyImagesTo(target, fields); return applied; }); diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 8b17f1ed4..328cbbaf1 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -81,8 +81,9 @@ grid-auto-rows: 141px; overflow-y: scroll; margin: 5px; + margin-top: 0px; width: calc(100% - 10px); - height: calc(100% - 51px); + height: calc(100% - 45px); border: 1px solid rgb(180, 180, 180); border-radius: 5px; @@ -240,8 +241,9 @@ align-items: center; overflow-y: scroll; margin: 5px; + margin-top: 0px; width: calc(100% - 10px); - height: calc(100% - 51px); + height: calc(100% - 45px); border: 1px solid rgb(180, 180, 180); border-radius: 5px; @@ -329,6 +331,11 @@ align-items: center; border-radius: 3px; border: solid 1px lightblue; + + &:hover { + border: solid 2px rgb(68, 153, 233); + z-index: 2; + } } } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index b1488679f..48b87fae7 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -38,7 +38,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _templateRefToDoc?: ObservableMap; @observable _selectedTemplate: Doc | undefined = undefined; - @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns: number, repeat: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, columns: 1, repeat: 0}; + @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns?: number, repeat: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, repeat: 0}; @observable _layoutPreview: boolean = true; @observable _layoutPreviewScale: number = 1; @@ -48,6 +48,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _indicatorY: number | undefined = undefined; @observable _display: boolean = false; + @observable _hoveredLayoutPreview: number | undefined = undefined; @observable _mouseX: number = -1; @observable _mouseY: number = -1; @observable _startPos?: {x: number, y: number}; @@ -68,7 +69,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action setTemplateDocs = (docs: Doc[]) => {this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc)}; @computed get docsToRender() { - return NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows); + return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : []; } @computed get rowsCount(){ @@ -255,6 +256,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + + get layoutPreviewContents() { const docWidth = Number(this._selectedTemplate?._width); const docHeight = Number(this._selectedTemplate?._height); @@ -298,6 +301,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { : this.docsToRender.map(num =>
this._dataViz?.setSpecialHighlightedRow(num)} + onMouseLeave={() => this._dataViz?.setSpecialHighlightedRow(undefined)} className='docCreatorMenu-layout-preview-item' style={{ width: scaledDown(docWidth), @@ -348,7 +353,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}
{layoutOption(LayoutType.Stacked)} - {layoutOption(LayoutType.Grid, undefined, () => {this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length))})} + {layoutOption(LayoutType.Grid, undefined, () => {if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length))})} {layoutOption(LayoutType.Row)} {layoutOption(LayoutType.Column)} {layoutOption(LayoutType.Custom, {borderBottom: `0px`})} @@ -432,7 +437,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { >
); } render() { + const topButton = (icon: string, func: Function, tag: string) => { + return ( +
+
this.setUpButtonClick(e, () => runInAction(() => {func()}))}> + +
+
+ ); + } + + const onPreviewSelected = () => {this._menuContent = 'templates'} + const onSavedSelected = () => {this._menuContent = 'saved'} + const onOptionsSelected = () => { + this._menuContent = 'options'; + if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length)); + } + + return (
{!this._shouldDisplay ? undefined : @@ -435,28 +468,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { onPointerMove={e => this.onPointerMove(e)} onPointerUp={() => this._dragging = false} > - - +
+ {topButton('table-cells', onPreviewSelected, 'left')} + {topButton('bars', onOptionsSelected, 'middle')} + {topButton('floppy-disk', onSavedSelected, 'right')} +
- +
+ + +
{ {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))}
+ ); + } + + get savedLayoutsPreviewContents(){ + return ( +
+ {this._savedLayouts.map((layout, index) => +
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))} + > + {this.layoutPreviewContents(87, layout, false, true, index)} +
+ )}
); } @@ -259,20 +296,23 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + layoutPreviewContents = (outerSpan: number, altLayout?: DataVizTemplateLayout, zoomOption: boolean = true, small: boolean = false, id?: number) => { + const doc: Doc | undefined = altLayout ? altLayout.template : this._selectedTemplate; + if (!doc) return; + const layout = altLayout ? altLayout.layout : this._layout; - get layoutPreviewContents() { - const docWidth = Number(this._selectedTemplate?._width); - const docHeight = Number(this._selectedTemplate?._height); - const horizontalSpan: number = (docWidth + this._layout.xMargin) * this.columnsCount - this._layout.xMargin; - const verticalSpan: number = (docHeight + this._layout.yMargin) * this.rowsCount - this._layout.yMargin; + const docWidth: number = Number(doc._width); + const docHeight: number = Number(doc._height); + const horizontalSpan: number = (docWidth + layout.xMargin) * (altLayout ? altLayout.columns : this.columnsCount) - layout.xMargin;; + const verticalSpan: number = (docHeight + layout.yMargin) * (altLayout ? altLayout.rows : this.rowsCount) - layout.yMargin; const largerSpan: number = horizontalSpan > verticalSpan ? horizontalSpan : verticalSpan; - const scaledDown = (input: number) => {return input / (largerSpan / 225 * this._layoutPreviewScale)} + const scaledDown = (input: number) => {return input / (largerSpan / outerSpan * this._layoutPreviewScale)} const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3)); return ( -
-
+
+ {!zoomOption ? null :
-
+
}
{this._layout.type === LayoutType.Stacked ?
{
{this._layout.type ? this.layoutConfigOptions: null} - {this._layoutPreview ? this.layoutPreviewContents : null} + {this._layoutPreview ? this.layoutPreviewContents(225) : null} {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))} - + + + +
); } + get renderSelectedViewType(){ + switch (this._menuContent){ + case 'templates': + return this.templatesPreviewContents; + case 'options': + return this.optionsMenuContents; + case 'saved': + return this.savedLayoutsPreviewContents; + default: + return undefined; + } + } + render() { const topButton = (icon: string, opt: string, func: Function, tag: string) => { return ( @@ -485,7 +555,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
- {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} + {this.renderSelectedViewType} } @@ -499,4 +569,12 @@ export interface DataVizTemplateInfo { layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number}; columns: number; referencePos: {x: number, y: number}; +} + +export interface DataVizTemplateLayout { + template: Doc; + docsNumList: number[]; + layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number}; + columns: number; + rows: number; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 19144140070f32f8ce9567d0197e809669e3e297 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:41:05 -0400 Subject: dragging fixed and resizing mostly working (no css yet) --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 29 ++++- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 133 ++++++++++++++++++--- 2 files changed, 146 insertions(+), 16 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index d18f75545..87f493291 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -228,7 +228,32 @@ } //------------------------------------------------------------------------------------------------------------------------------------------ -//DocCreatorMenu templates preview CSS +// Resizers CSS +//-------------------------------------------------------------------------------------------------------------------------------------------- + +.docCreatorMenu-resizer { + position: absolute; + background-color: none; + + &.top, &.bottom { + height: 10px; + cursor: ns-resize; + } + + &.right, &.left { + width: 10px; + cursor: ew-resize; + } + + &.topRight, &.topLeft, &.bottomRight, &.bottomLeft { + height: 10px; + width: 10px; + background-color: blue; + } +} + +//------------------------------------------------------------------------------------------------------------------------------------------ +// DocCreatorMenu templates preview CSS //-------------------------------------------------------------------------------------------------------------------------------------------- @@ -274,7 +299,7 @@ } //------------------------------------------------------------------------------------------------------------------------------------------ -//DocCreatorMenu options CSS +// DocCreatorMenu options CSS //-------------------------------------------------------------------------------------------------------------------------------------------- .docCreatorMenu-option-container{ diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index e48a6ada4..bc04f9a69 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -8,7 +8,7 @@ import { DocCast, ImageCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; import { SnappingManager } from '../../../util/SnappingManager'; -import { undoable } from '../../../util/UndoManager'; +import { UndoManager, undoable } from '../../../util/UndoManager'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../DocumentView'; import { DataVizBox } from './DataVizBox'; @@ -18,6 +18,8 @@ import { Colors, IconButton, Size } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; import { threadId } from 'worker_threads'; import { ideahub } from 'googleapis/build/src/apis/ideahub'; +import { DragManager } from '../../../util/DragManager'; +import { DateField } from '../../../../fields/DateField'; export enum LayoutType { Stacked = 'stacked', @@ -58,6 +60,14 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _dragging: boolean = false; @observable _draggingIndicator: boolean = false; @observable _dataViz?: DataVizBox; + @observable _interactionLock: any; + @observable _snapPt: any; + @observable _resizeHdlId: string = ''; + @observable _resizing: boolean = false; + @observable _offset: {x: number, y: number} = {x: 0, y: 0}; + @observable _resizeUndo: UndoManager.Batch | undefined = undefined; + @observable _initDimensions: {width: number, height: number, x: number, y: number} = {width: 300, height: 400, x: 0, y: 0}; + @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 400}; constructor(props: any) { super(props); @@ -102,6 +112,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return this._selectedTemplate !== undefined && this._layout !== undefined; } + get bounds(): {t: number, b: number, l: number, r: number} { + const rect = this._ref?.getBoundingClientRect(); + const bounds = {t: rect?.top ?? 0, b: rect?.bottom ?? 0, l: rect?.left ?? 0, r: rect?.right ?? 0}; + return bounds; + } + setUpButtonClick = (e: any, func: Function) => { setupMoveUpEvents( this, @@ -123,6 +139,19 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action onPointerUp = (e: PointerEvent) => { + if (this._resizing) { + this._initDimensions.width = this._menuDimensions.width; + this._initDimensions.height = this._menuDimensions.height; + this._initDimensions.x = this._pageX; + this._initDimensions.y = this._pageY; + document.removeEventListener('pointermove', this.onResize); + SnappingManager.SetIsResizing(undefined); + this._resizing = false; + } + if (this._dragging) { + document.removeEventListener('pointermove', this.onDrag); + this._dragging = false; + } if (e.button !== 2 && !e.ctrlKey) return; const curX = e.clientX; const curY = e.clientY; @@ -164,17 +193,76 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { }; @action - onPointerMove = (e: any) => { - // if (this._draggingIndicator) { - // this._indicatorX = e.pageX - (this._startPos?.x ?? 0) + this._pageX; - // this._indicatorY = e.pageY - (this._startPos?.y ?? 0) + this._pageY; - // } else - if (this._dragging){ - this._pageX = e.pageX - (this._startPos?.x ?? 0); - this._pageY = e.pageY - (this._startPos?.y ?? 0); - } + onResizePointerDown = (e: React.PointerEvent): void => { + this._resizing = true; + document.addEventListener('pointermove', this.onResize); + SnappingManager.SetIsResizing(DocumentView.Selected().lastElement()?.Document[Id]); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them + e.stopPropagation(); + const id = (this._resizeHdlId = e.currentTarget.className); + const pad = id.includes('Left') || id.includes('Right') ? Number(getComputedStyle(e.target as any).width.replace('px', '')) / 2 : 0; + const bounds = e.currentTarget.getBoundingClientRect(); + this._offset = { + x: id.toLowerCase().includes('left') ? bounds.right - e.clientX - pad : bounds.left - e.clientX + pad, // + y: id.toLowerCase().includes('top') ? bounds.bottom - e.clientY - pad : bounds.top - e.clientY + pad, + }; + this._resizeUndo = UndoManager.StartBatch('drag resizing'); + this._snapPt = { x: e.pageX, y: e.pageY }; + }; + + @action + onResize = (e: any): boolean => { + const dragHdl = this._resizeHdlId.split(' ')[1]; + const thisPt = DragManager.snapDrag(e, -this._offset.x, -this._offset.y, this._offset.x, this._offset.y); + + const { scale, refPt, transl } = this.getResizeVals(thisPt, dragHdl); + !this._interactionLock && runInAction(async () => { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate) + this._interactionLock = true; + const scaleAspect = {x: scale.x, y: scale.y}; + this.resizeView(refPt, scaleAspect, transl); // prettier-ignore + await new Promise(res => { setTimeout(() => { res(this._interactionLock = undefined)})}); + }); // prettier-ignore + return true; } + @action + onDrag = (e: any): boolean => { + this._pageX = e.pageX - (this._startPos?.x ?? 0); + this._pageY = e.pageY - (this._startPos?.y ?? 0); + return true; + } + + getResizeVals = (thisPt: { x: number; y: number }, dragHdl: string) => { + const [w, h] = [this._initDimensions.width, this._initDimensions.height]; + const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y]; + let vals: {scale: {x: number, y: number}, refPt: [number, number], transl: {x: number, y: number}}; + switch (dragHdl) { + case 'topLeft': vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: -moveY } }; break; + case 'topRight': vals = { scale: { x: 1 + moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: -moveY } }; break; + case 'top': vals = { scale: { x: 1, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: moveY } }; break; + case 'left': vals = { scale: { x: 1 - moveX / w, y: 1 }, refPt: [this.bounds.r, this.bounds.t], transl: {x: moveX, y: 0 } }; break; + case 'bottomLeft': vals = { scale: { x: 1 - moveX / w, y: 1 + moveY / h }, refPt: [this.bounds.r, this.bounds.t], transl: {x: moveX, y: moveY } }; break; + case 'right': vals = { scale: { x: 1 + moveX / w, y: 1 }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; + case 'bottomRight':vals = { scale: { x: 1 + moveX / w, y: 1 + moveY / h }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; + case 'bottom': vals = { scale: { x: 1, y: 1 + moveY / h }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; + default: vals = { scale: { x: 1, y: 1 }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; + } // prettier-ignore + return vals; + }; + + resizeView = (refPt: number[], scale: { x: number; y: number }, translation: {x: number, y: number}) => { + const refCent = [refPt[0], refPt[1]] // fixed reference point for resize (ie, a point that doesn't move) + if (this._initDimensions.x === undefined) this._initDimensions.x = this._pageX; + if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY; + const {height, width, x, y} = this._initDimensions; + + console.log(scale.x) + + this._menuDimensions.width = Math.max(100, scale.x * width); + this._menuDimensions.height = Math.max(100, scale.y * height); + this._pageX = x + translation.x; + this._pageY = y + translation.y; + }; + async getIcon(doc: Doc) { const docView = DocumentView.getDocumentView(doc); if (docView) { @@ -470,6 +558,23 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + get resizePanes(){ + const ref = this._ref?.getBoundingClientRect(); + const height: number = ref?.height ?? 0; + const width: number = ref?.width ?? 0; + + return [ +
, +
, +
, +
, +
, +
, +
, +
+ ]; //prettier-ignore + } + render() { const topButton = (icon: string, opt: string, func: Function, tag: string) => { return ( @@ -526,11 +631,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { display: '', left: this._pageX, top: this._pageY, - width: 300, - height: 400, + width: this._menuDimensions.width, + height: this._menuDimensions.height, background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, }}> + {this.resizePanes}
@@ -542,6 +648,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { this._startPos = {x: 0, y: 0}; this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0); this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0); + document.addEventListener('pointermove', this.onDrag); return true; }, emptyFunction, @@ -550,8 +657,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { }, 'drag menu') ) } - onPointerMove={e => this.onPointerMove(e)} - onPointerUp={() => this._dragging = false} >
{topButton('table-cells', 'templates', onPreviewSelected, 'left')} -- cgit v1.2.3-70-g09d2 From 598bc954df87bc6d5875c404cefc6f26b51f6afe Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:05:09 -0400 Subject: resizing 90% --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 15 ++++++++------- src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 87f493291..ac60ddb3e 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -246,9 +246,9 @@ } &.topRight, &.topLeft, &.bottomRight, &.bottomLeft { - height: 10px; - width: 10px; - background-color: blue; + height: 15px; + width: 15px; + background-color: none; } } @@ -504,10 +504,11 @@ flex: 0 0 auto; overflow: scroll; display: grid; - width: auto; - height: auto; - max-width: 240; - max-height: 240; + width: 100%; + aspect-ratio: 1.23; + //height: auto; + // max-width: 240; + // max-height: 240; border: 1px solid rgb(180, 180, 180); border-radius: 5px; background-color: rgb(34, 34, 37); diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index bc04f9a69..ef53dde8e 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -66,7 +66,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _resizing: boolean = false; @observable _offset: {x: number, y: number} = {x: 0, y: 0}; @observable _resizeUndo: UndoManager.Batch | undefined = undefined; - @observable _initDimensions: {width: number, height: number, x: number, y: number} = {width: 300, height: 400, x: 0, y: 0}; + @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined}; @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 400}; constructor(props: any) { @@ -228,6 +228,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { onDrag = (e: any): boolean => { this._pageX = e.pageX - (this._startPos?.x ?? 0); this._pageY = e.pageY - (this._startPos?.y ?? 0); + this._initDimensions.x = this._pageX; + this._initDimensions.y = this._pageY; return true; } @@ -236,11 +238,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y]; let vals: {scale: {x: number, y: number}, refPt: [number, number], transl: {x: number, y: number}}; switch (dragHdl) { - case 'topLeft': vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: -moveY } }; break; - case 'topRight': vals = { scale: { x: 1 + moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: -moveY } }; break; + case 'topLeft': vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: moveY } }; break; + case 'topRight': vals = { scale: { x: 1 + moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: moveY } }; break; case 'top': vals = { scale: { x: 1, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: moveY } }; break; case 'left': vals = { scale: { x: 1 - moveX / w, y: 1 }, refPt: [this.bounds.r, this.bounds.t], transl: {x: moveX, y: 0 } }; break; - case 'bottomLeft': vals = { scale: { x: 1 - moveX / w, y: 1 + moveY / h }, refPt: [this.bounds.r, this.bounds.t], transl: {x: moveX, y: moveY } }; break; + case 'bottomLeft': vals = { scale: { x: 1 - moveX / w, y: 1 + moveY / h }, refPt: [this.bounds.r, this.bounds.t], transl: {x: moveX, y: 0 } }; break; case 'right': vals = { scale: { x: 1 + moveX / w, y: 1 }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; case 'bottomRight':vals = { scale: { x: 1 + moveX / w, y: 1 + moveY / h }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; case 'bottom': vals = { scale: { x: 1, y: 1 + moveY / h }, refPt: [this.bounds.l, this.bounds.t], transl: {x: 0, y: 0 } }; break; @@ -255,8 +257,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY; const {height, width, x, y} = this._initDimensions; - console.log(scale.x) - this._menuDimensions.width = Math.max(100, scale.x * width); this._menuDimensions.height = Math.max(100, scale.y * height); this._pageX = x + translation.x; @@ -568,10 +568,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
,
,
, -
, -
, -
, -
+
, +
, +
, +
]; //prettier-ignore } -- cgit v1.2.3-70-g09d2 From 107c389f61df36b464ae3ec73e2f553a78f3e64a Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:39:46 -0400 Subject: layout preview sizing --- src/client/views/nodes/DataVizBox/DocCreatorMenu.scss | 4 ++-- src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 5 +---- src/client/views/nodes/LabelBox.tsx | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index ac60ddb3e..81fd3386c 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -222,7 +222,7 @@ .docCreatorMenu-option-divider { border-top: 1px solid rgb(180, 180, 180); - width: 225px; + width: 80%; margin-top: 10px; margin-bottom: 10px; } @@ -505,7 +505,7 @@ overflow: scroll; display: grid; width: 100%; - aspect-ratio: 1.23; + aspect-ratio: 1; //height: auto; // max-width: 240; // max-height: 240; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index ef53dde8e..e5288f4f8 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -16,10 +16,7 @@ import './DocCreatorMenu.scss'; import { Id } from '../../../../fields/FieldSymbols'; import { Colors, IconButton, Size } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; -import { threadId } from 'worker_threads'; -import { ideahub } from 'googleapis/build/src/apis/ideahub'; import { DragManager } from '../../../util/DragManager'; -import { DateField } from '../../../../fields/DateField'; export enum LayoutType { Stacked = 'stacked', @@ -509,7 +506,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._layout.type ? this.layoutConfigOptions: null} - {this._layoutPreview ? this.layoutPreviewContents(225) : null} + {this._layoutPreview ? this.layoutPreviewContents(this._menuDimensions.width * .75) : null} {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => ))}
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index d33d12603..1f5fa8e14 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -2,7 +2,7 @@ import { Property } from 'csstype'; import { action, computed, makeObservable, trace } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import * as textfit from 'textfit'; +//import * as textfit from 'textfit'; import { Field, FieldType } from '../../../fields/Doc'; import { BoolCast, NumCast, StrCast } from '../../../fields/Types'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -95,7 +95,7 @@ export class LabelBox extends ViewBoxBaseComponent() { this._timeout = setTimeout(() => this.fitTextToBox(r)); return textfitParams; } - textfit(r, textfitParams); + //textfit(r, textfitParams); } return textfitParams; }; -- cgit v1.2.3-70-g09d2 From fb4b4658f39c2a845174372a8fd814c49bf26d7c Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:00:12 -0400 Subject: template preview columns update with resizing --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 2 +- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 3 +- src/fields/Doc.ts | 64 ++++++++++++++++++---- 3 files changed, 55 insertions(+), 14 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 81fd3386c..b3bacb13c 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -259,7 +259,7 @@ .docCreatorMenu-preview-container { display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(2, 140px); grid-template-rows: 140px; grid-auto-rows: 141px; overflow-y: scroll; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index e5288f4f8..34bec3b88 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -296,7 +296,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; return ( -
+
{this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { if (renderedTemplates.includes(info.doc)) return undefined; renderedTemplates.push(info.doc); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 2792f3aba..5a4573a4f 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable default-param-last */ /* eslint-disable no-use-before-define */ import { action, computed, makeObservable, observable, ObservableMap, ObservableSet, runInAction } from 'mobx'; @@ -38,7 +36,7 @@ export namespace Field { * @param showComputedValue whether copmuted function should display its value instead of its function * @returns string representation of the field */ - export function toKeyValueString(doc: Doc, key: string, showComputedValue?: boolean): string { + export function toKeyValueString(doc: Doc, key: string, showComputedValue?: boolean, schemaCell?: boolean): string { const isOnDelegate = !Doc.IsDataProto(doc) && Object.keys(doc).includes(key.replace(/^_/, '')); const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); const valFunc = (field: FieldType): string => { @@ -49,7 +47,7 @@ export namespace Field { ? `:=${field.script.originalScript.replace(/dashCallChat\(_setCacheResult_, this, `(.*)`\)/, '(($1))')}` : field instanceof ScriptField ? `$=${field.script.originalScript}` - : Field.toScriptString(field); + : Field.toScriptString(field, schemaCell); const resStr = (res + '').replace(/^`(.*)`$/, '$1'); return typeof field === 'string' && (+resStr).toString() !== resStr && !Array.from('+-*/.').some(k => Array.from(resStr).includes(k)) ? resStr @@ -59,10 +57,10 @@ export namespace Field { }; return !Field.IsField(cfield) ? (key.startsWith('_') ? '=' : '') : (isOnDelegate ? '=' : '') + valFunc(cfield); } - export function toScriptString(field: FieldType) { + export function toScriptString(field: FieldType, schemaCell?: boolean) { switch (typeof field) { case 'string': if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s - return !field.includes('`') ? `\`${field}\`` : `"${field}"`; + return !field.includes('`') ? schemaCell ? `${field}` : `\`${field}\`` : `"${field}"`; case 'number': case 'boolean':return String(field); default: return field?.[ToScriptString]?.() ?? 'null'; @@ -176,6 +174,49 @@ export function updateCachedAcls(doc: Doc) { return undefined; } +export function ActiveInkPen(): Doc { return Doc.UserDoc(); } // prettier-ignore +export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, 'black'); } // prettier-ignore +export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ''); } // prettier-ignore +export function ActiveIsInkMask(): boolean { return BoolCast(ActiveInkPen()?.activeIsInkMask, false); } // prettier-ignore +export function ActiveInkHideTextLabels(): boolean { return BoolCast(ActiveInkPen().activeInkHideTextLabels, false); } // prettier-ignore +export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ''); } // prettier-ignore +export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ''); } // prettier-ignore +export function ActiveArrowScale(): number { return NumCast(ActiveInkPen()?.activeArrowScale, 1); } // prettier-ignore +export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, '0'); } // prettier-ignore +export function ActiveInkWidth(): number { return Number(ActiveInkPen()?.activeInkWidth); } // prettier-ignore +export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); } // prettier-ignore + +export function SetActiveInkWidth(width: string): void { + !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width); +} +export function SetActiveBezierApprox(bezier: string): void { + ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier); +} +export function SetActiveInkColor(value: string) { + ActiveInkPen() && (ActiveInkPen().activeInkColor = value); +} +export function SetActiveIsInkMask(value: boolean) { + ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value); +} +export function SetActiveInkHideTextLabels(value: boolean) { + ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = value); +} +export function SetActiveFillColor(value: string) { + ActiveInkPen() && (ActiveInkPen().activeFillColor = value); +} +export function SetActiveArrowStart(value: string) { + ActiveInkPen() && (ActiveInkPen().activeArrowStart = value); +} +export function SetActiveArrowEnd(value: string) { + ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value); +} +export function SetActiveArrowScale(value: number) { + ActiveInkPen() && (ActiveInkPen().activeArrowScale = value); +} +export function SetActiveDash(dash: string): void { + !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); +} + @scriptingGlobal @Deserializable('Doc', updateCachedAcls, ['id']) export class Doc extends RefField { @@ -212,7 +253,7 @@ export class Doc extends RefField { public static DeleteLink: (link: Doc) => void; public static Links: (link: Doc | undefined) => Doc[]; public static getOppositeAnchor: (linkDoc: Doc, anchor: Doc) => Doc | undefined; - // KeyValue SetField + // KeyValueBox SetField (defined there) public static SetField: (doc: Doc, key: string, value: string, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => boolean; // UserDoc "API" public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); } // prettier-ignore @@ -1044,12 +1085,13 @@ export namespace Doc { const target = Doc.MakeDelegate(proto); const targetKey = StrCast(templateDoc.layout_fieldKey, 'layout'); const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + '(...' + _applyCount++ + ')'); - target.layout_fieldKey = targetKey; + target.layout_fieldKey = targetKey; //this and line above applied && (Doc.GetProto(applied).type = templateDoc.type); return applied; } return undefined; } + export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) { if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) { if (target.resolvedDataDoc) { @@ -1256,12 +1298,10 @@ export namespace Doc { document.removeEventListener('pointerdown', linkFollowUnhighlight); document.addEventListener('pointerdown', linkFollowUnhighlight); if (UnhighlightTimer) clearTimeout(UnhighlightTimer); - const presTransition = Number(presentationEffect?.presentation_transition); - const duration = isNaN(presTransition) ? 5000 : presTransition; UnhighlightTimer = window.setTimeout(() => { linkFollowUnhighlight(); UnhighlightTimer = 0; - }, duration); + }, 5000); } export const highlightedDocs = new ObservableSet(); @@ -1314,7 +1354,7 @@ export namespace Doc { doc._lockedPosition = !doc._lockedPosition; doc._pointerEvents = doc._lockedPosition ? 'none' : undefined; } - + export function deiconifyView(doc: Doc) { StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc); } -- cgit v1.2.3-70-g09d2 From 4949c68f38049da55ceaa3e95ea155f38d6a3748 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 8 Aug 2024 10:38:35 -0400 Subject: UI for GPT templates in doccreator menu --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 45 ------- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 128 ++++++++++++++++-- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 147 ++++++++++++++++----- src/client/views/nodes/ImageBox.tsx | 1 + 4 files changed, 228 insertions(+), 93 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index c5a1da1da..a6d3bfa49 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -568,51 +568,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { this.applyLayout(templateInfo, docs); } - generateTemplates = async () => { - try { - const res = await gptAPICall('Please generate for the fields: Image, Description, Divider, Response', GPTCallType.TEMPLATE); - - if (res) { - const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res); - this.createGeneratedTemplates(templates, 500, 500); - //console.log(res); - } - } catch (err) { - console.error(err); - } - - } - - createGeneratedTemplates = (layouts: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[], tempWidth: number, tempHeight: number) => { - const mainCollection = this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; - - layouts.forEach(layout => { - const fields: Doc[] = layout.fieldVals.map(field => { - const left: number = Number(field.tlx) * tempWidth / 2; const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore - const right: number = Number(field.brx) * tempWidth / 2; const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore - const height = bottom - top; const width = right - left; //prettier-ignore - const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: 250, title: field.title.replace(/$$/g, ''), x: left, y: top }); - return doc; - }); - - const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400, y: 400 }); - mainCollection.addDocument(template); - }); - } - - createBasicTemplates = (colsToLayout: {width: number, height: number, x: number, y: number, title: string}[]) => { - const mainCollection = this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; - - const fields: Doc[] = colsToLayout.map(layout => { - const field = Docs.Create.TextDocument('', { _height: layout.height, _width: layout.width, title: layout.title, x: layout.x, y: layout.y }); - return field; - }); - - const template = Docs.Create.FreeformDocument(fields, { _height: 500, _width: 500, title: 'template', x: 400, y: 400 }) - - mainCollection.addDocument(template); - } - /** * creates a new dataviz document filter from this one * it appears to the right of this document, with the diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index b3bacb13c..e2b4014bd 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -22,14 +22,14 @@ } .docCreatorMenu-menu-button { - width: 30px; - height: 30px; + width: 25px; + height: 25px; background: whitesmoke; - background-color: rgb(34, 34, 37); + background-color: rgb(50, 50, 50); border-radius: 5px; border: 1px solid rgb(180, 180, 180); padding: 0px; - font-size: 14px; + font-size: 13px; //box-shadow: 3px 3px rgb(29, 29, 31); &:hover { @@ -222,7 +222,7 @@ .docCreatorMenu-option-divider { border-top: 1px solid rgb(180, 180, 180); - width: 80%; + width: 95%; margin-top: 10px; margin-bottom: 10px; } @@ -256,6 +256,18 @@ // DocCreatorMenu templates preview CSS //-------------------------------------------------------------------------------------------------------------------------------------------- +.docCreatorMenu-templates-view { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + margin: 5px; + margin-top: 0px; + width: calc(100% - 10px); + height: calc(100% - 30px); + border: 1px solid rgb(180, 180, 180); + border-radius: 5px; +} .docCreatorMenu-preview-container { display: grid; @@ -263,20 +275,18 @@ grid-template-rows: 140px; grid-auto-rows: 141px; overflow-y: scroll; - margin: 5px; + margin: 0px; margin-top: 0px; - width: calc(100% - 10px); - height: calc(100% - 30px); - border: 1px solid rgb(180, 180, 180); - border-radius: 5px; + width: 100%; + height: 100%; } .docCreatorMenu-preview-window { display: flex; justify-content: center; align-items: center; - width: 125px; - height: 125px; + width: 113px; + height: 113px; margin-top: 10px; margin-left: 10px; border: 1px solid rgb(163, 163, 163); @@ -295,9 +305,103 @@ &.empty { font-size: 35px; + flex: 0 0 auto; + + &.GPT { + margin-top: 0px; + } + } +} + +.docCreatorMenu-section { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; + margin: 0px; + width: 100%; + height: 250; + flex: 0 0 auto; +} + +.docCreatorMenu-GPT-options-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + position: relative; + width: auto; + margin: 0px; + margin-top: 5px; + padding: 0px; +} + +.docCreatorMenu-GPT-templates-preview { + display: flex; + flex-direction: row; + //justify-content: center; + align-items: center; + overflow-y: scroll; + position: relative; + height: 125px; + width: calc(100% - 10px); + -ms-overflow-style: none; + scrollbar-width: none; +} + +.docCreatorMenu-section-topbar { + position: relative; + display: flex; + flex-direction: row; + width: 100%; + + .section-reveal-options { + margin: 0px; + margin-left: auto; + border: 0px; + background: none; + } +} + +.docCreatorMenu-section-title { + border: 1px solid rgb(163, 163, 163); + border-top: 0px; + border-left: 0px; + border-bottom-right-radius: 5px; + font-size: 12px; + padding: 2px; + padding-left: 3px; + padding-right: 3px; + margin-bottom: 3px; +} + +.docCreatorMenu-GPT-generate { + height: 30px; + width: 30px; + background-color: rgb(176, 229, 149); + border: 1px solid rgb(126, 219, 80); + border-radius: 5px; + padding: 0px; + font-size: 14px; + color: white; + letter-spacing: 1px; + flex: 0 0 auto; + + &:hover { + background-color: rgb(129, 223, 83); + border: 2px solid rgb(80, 185, 28); } } +.docCreatorMenu-GPT-prompt-input { + width: 140px; + overflow-y: scroll; + border: 1px solid rgb(180, 180, 180); + background-color: rgb(35, 35, 35); + border-radius: 3px; +} + //------------------------------------------------------------------------------------------------------------------------------------------ // DocCreatorMenu options CSS //-------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 411257ff7..781cbcb55 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -3,7 +3,7 @@ import { IReactionDisposer, ObservableMap, action, computed, makeObservable, obs import { observer } from 'mobx-react'; import * as React from 'react'; import { returnAll, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; -import { Doc, NumListCast } from '../../../../fields/Doc'; +import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc'; import { DocCast, ImageCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; @@ -17,6 +17,9 @@ import { Id } from '../../../../fields/FieldSymbols'; import { Colors, IconButton, Size } from 'browndash-components'; import { MakeTemplate } from '../../../util/DropConverter'; import { DragManager } from '../../../util/DragManager'; +import { GPTCallType, gptAPICall } from '../../../apis/gpt/GPT'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; +import { Docs } from '../../../documents/Documents'; export enum LayoutType { Stacked = 'stacked', @@ -41,6 +44,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _layoutPreviewScale: number = 1; @observable _savedLayouts: DataVizTemplateLayout[] = []; + @observable _GPTTemplates: Doc[] | undefined = undefined; + @observable _GPTOpt: boolean = false; + @observable _userPrompt: string = ''; + @observable _pageX: number = 0; @observable _pageY: number = 0; @observable _indicatorX: number | undefined = undefined; @@ -105,6 +112,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + @computed get selectedFields(){ + return StrListCast(this._dataViz?.layoutDoc._dataViz_axes); + } + @computed get canMakeDocs(){ return this._selectedTemplate !== undefined && this._layout !== undefined; } @@ -254,8 +265,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY; const {height, width, x, y} = this._initDimensions; - this._menuDimensions.width = Math.max(100, scale.x * width); - this._menuDimensions.height = Math.max(100, scale.y * height); + this._menuDimensions.width = Math.max(300, scale.x * width); + this._menuDimensions.height = Math.max(200, scale.y * height); this._pageX = x + translation.x; this._pageY = y + translation.y; }; @@ -293,10 +304,104 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { && this._layout.columns === layout.columns; } + generateTemplates = async (inputText: string) => { + let prompt: string = 'Please generate for the fields:'; + this.selectedFields?.forEach(field => prompt += ` ${field},`) + prompt += ` Additional prompt: ${inputText}`; + + try { + const res = await gptAPICall(prompt, GPTCallType.TEMPLATE); + + if (res) { + const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res); + this.createGeneratedTemplates(templates, 500, 500); + } + } catch (err) { + console.error(err); + } + + } + + createGeneratedTemplates = (layouts: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[], tempWidth: number, tempHeight: number) => { + const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + + layouts.forEach(layout => { + const fields: Doc[] = layout.fieldVals.map(field => { + const left: number = Number(field.tlx) * tempWidth / 2; const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore + const right: number = Number(field.brx) * tempWidth / 2; const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore + const height = bottom - top; + const width = right - left; + const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/$$/g, ''), x: left, y: top }); + return doc; + }); + + const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400, y: 400 }); + mainCollection.addDocument(template); + }); + } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; + + const GPTOptions = +
+ + return ( -
+
+
+
Suggested Templates
+ +
+
+
+
+
+
+
+ {this._GPTOpt ? (
+
+ + +
+ {this._GPTOpt ? GPTOptions : null} +
) : null} +
+
+
+
+
Your Templates
+ +
+
+
this.setUpButtonClick(e, this.basicTemplateTest)} + > + +
+ {this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { + if (renderedTemplates.includes(info.doc)) return undefined; + renderedTemplates.push(info.doc); + return (
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> + +
+ )})} +
+
+ {/*
{this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { if (renderedTemplates.includes(info.doc)) return undefined; @@ -316,6 +421,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { >
+
*/}
); } @@ -546,12 +652,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } basicTemplateTest = () => { - const temps: {width: number; height: number; x: number; y: number; title: string}[] = [ - {width: 200, height: 50, x: -100, y: -200, title: 'title'}, - {width: 300, height: 300, x: -150, y: -100, title: 'image'}, - {width: 200, height: 50, x: -100, y: -200, title: 'description'}, - ] - this._dataViz?.generateTemplates(); + this.generateTemplates(this._userPrompt); //this._dataViz?.createBasicTemplates(temps); } @@ -609,31 +710,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return (
{!this._shouldDisplay ? undefined : - <> - {/*
this.onPointerMove(e)} - onPointerDown={e => - setupMoveUpEvents( - this, - e, - (e) => { - this._draggingIndicator = true; - this._startPos = {x: 0, y: 0}; - this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0); - this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0); - return true; - }, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - }, 'drag menu') - ) - }/> */}
this._ref = r} @@ -681,7 +757,6 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this.renderSelectedViewType}
- }
) diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 92a5a1533..faea05104 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -295,6 +295,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { @computed get nativeSize() { TraceMobx(); + if (this.paths.length && this.paths[0].includes('icon-hi')) return { nativeWidth: NumCast(this.layoutDoc._width), nativeHeight: NumCast(this.layoutDoc._height), nativeOrientation: 0} const nativeWidth = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth'], 500)); const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '_nativeHeight'], 500)); const nativeOrientation = NumCast(this.dataDoc[this.fieldKey + '_nativeOrientation'], 1); -- cgit v1.2.3-70-g09d2 From 541d380f1ff7957f9e3d66965761b074fec073c3 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sat, 10 Aug 2024 19:36:29 -0400 Subject: UI --- src/client/views/nodes/DataVizBox/DocCreatorMenu.scss | 14 ++++++++++---- src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index e2b4014bd..82a659ff7 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -225,6 +225,10 @@ width: 95%; margin-top: 10px; margin-bottom: 10px; + + &.full { + width: 100%; + } } //------------------------------------------------------------------------------------------------------------------------------------------ @@ -259,14 +263,15 @@ .docCreatorMenu-templates-view { display: flex; flex-direction: column; - justify-content: center; - align-items: flex-start; + justify-content: flex-start; + //align-items: flex-start; margin: 5px; margin-top: 0px; width: calc(100% - 10px); height: calc(100% - 30px); border: 1px solid rgb(180, 180, 180); border-radius: 5px; + overflow: hidden; } .docCreatorMenu-preview-container { @@ -316,12 +321,13 @@ .docCreatorMenu-section { display: flex; flex-direction: column; - justify-content: center; align-items: center; position: relative; margin: 0px; + margin-top: 0px; + margin-bottom: 0px; width: 100%; - height: 250; + height: 200; flex: 0 0 auto; } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 781cbcb55..2efd73136 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -372,7 +372,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { {this._GPTOpt ? GPTOptions : null}
) : null}
-
+
Your Templates
-- cgit v1.2.3-70-g09d2 From afd43afb6b75a7af0032ee14c79d1dd7ffedcac4 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:28:57 -0400 Subject: generated templates appear in menu --- src/client/views/MainView.tsx | 1 + .../views/nodes/DataVizBox/DocCreatorMenu.scss | 4 +- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 95 ++++++++++++---------- 3 files changed, 54 insertions(+), 46 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index dd5884cf2..d4467e536 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -279,6 +279,7 @@ export class MainView extends ObservableReactComponent<{}> { library.add( ...[ + fa.faArrowsRotate, fa.faFloppyDisk, fa.faRepeat, fa.faArrowsUpDown, diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 82a659ff7..3b6aeb0dd 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -297,6 +297,7 @@ border: 1px solid rgb(163, 163, 163); border-radius: 5px; box-shadow: 5px 5px rgb(29, 29, 31); + flex: 0 0 auto; &:hover{ background-color: rgb(72, 72, 73); @@ -310,7 +311,6 @@ &.empty { font-size: 35px; - flex: 0 0 auto; &.GPT { margin-top: 0px; @@ -402,10 +402,12 @@ .docCreatorMenu-GPT-prompt-input { width: 140px; + height: 25px; overflow-y: scroll; border: 1px solid rgb(180, 180, 180); background-color: rgb(35, 35, 35); border-radius: 3px; + padding-left: 4px; } //------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 2efd73136..b45ac7f46 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -44,7 +44,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _layoutPreviewScale: number = 1; @observable _savedLayouts: DataVizTemplateLayout[] = []; - @observable _GPTTemplates: Doc[] | undefined = undefined; + @observable _GPTTemplates: Doc[] = []; @observable _GPTOpt: boolean = false; @observable _userPrompt: string = ''; @@ -71,7 +71,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _offset: {x: number, y: number} = {x: 0, y: 0}; @observable _resizeUndo: UndoManager.Batch | undefined = undefined; @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined}; - @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 400}; + @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 365}; constructor(props: any) { super(props); @@ -81,6 +81,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz }; @action setTemplateDocs = (docs: Doc[]) => {this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc)}; + @action setGPTTemplates = (docs: Doc[]) => {this._GPTTemplates = docs}; @computed get docsToRender() { return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : []; @@ -169,14 +170,17 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { }; _disposer: IReactionDisposer | undefined; + _GPTDisposer: IReactionDisposer | undefined; componentDidMount() { document.addEventListener('pointerdown', this.onPointerDown, true); document.addEventListener('pointerup', this.onPointerUp); this._disposer = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon)); + this._GPTDisposer = reaction(() => this._GPTTemplates.slice(), (docs) => docs.map(this.getIcon)); } componentWillUnmount() { this._disposer?.(); + this._GPTDisposer?.(); document.removeEventListener('pointerdown', this.onPointerDown, true); document.removeEventListener('pointerup', this.onPointerUp); } @@ -275,7 +279,9 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const docView = DocumentView.getDocumentView(doc); if (docView) { docView.ComponentView?.updateIcon?.(); - return new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500)); + const f = new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500)); + console.log(f) + return f; } return undefined; } @@ -304,10 +310,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { && this._layout.columns === layout.columns; } + @action generateTemplates = async (inputText: string) => { let prompt: string = 'Please generate for the fields:'; this.selectedFields?.forEach(field => prompt += ` ${field},`) prompt += ` Additional prompt: ${inputText}`; + console.log(prompt) try { const res = await gptAPICall(prompt, GPTCallType.TEMPLATE); @@ -322,8 +330,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } + @action createGeneratedTemplates = (layouts: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[], tempWidth: number, tempHeight: number) => { const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + const GPTTemplates: Doc[] = []; layouts.forEach(layout => { const fields: Doc[] = layout.fieldVals.map(field => { @@ -335,9 +345,15 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return doc; }); - const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400, y: 400 }); + const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 40000, y: 40000 }); mainCollection.addDocument(template); + + GPTTemplates.push(template); }); + + setTimeout(() => this.setGPTTemplates(GPTTemplates), 500); + + this.forceUpdate(); } get templatesPreviewContents(){ @@ -346,10 +362,9 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const GPTOptions =
- return (
-
+
Suggested Templates
-
-
-
-
+ {this._GPTTemplates?.map(doc => + + //
+ ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => +
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> + +
+ )}
{this._GPTOpt ? (
- + this._userPrompt = e.target.value}/>
{this._GPTOpt ? GPTOptions : null}
) : null} @@ -387,41 +412,20 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
{this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { - if (renderedTemplates.includes(info.doc)) return undefined; - renderedTemplates.push(info.doc); - return (
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> - -
+ if (renderedTemplates.includes(info.doc)) return undefined; + renderedTemplates.push(info.doc); + return (
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> + +
)})}
- {/*
- {this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { - if (renderedTemplates.includes(info.doc)) return undefined; - renderedTemplates.push(info.doc); - return (
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> - -
- )})} -
this.setUpButtonClick(e, this.basicTemplateTest)} - > - -
-
*/}
); } @@ -652,7 +656,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } basicTemplateTest = () => { - this.generateTemplates(this._userPrompt); + console.log(this._GPTTemplates) + this.forceUpdate(); //this._dataViz?.createBasicTemplates(temps); } -- cgit v1.2.3-70-g09d2 From 8d3ef2ead4fb8a8625b7fbfe57e528819a030474 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 11 Aug 2024 04:07:40 -0400 Subject: edit and copy buttons added to GPT template preview --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 41 ++++++++++++++++++---- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 15 ++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 3b6aeb0dd..5a9fd3436 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -287,6 +287,7 @@ } .docCreatorMenu-preview-window { + position: relative; display: flex; justify-content: center; align-items: center; @@ -316,6 +317,34 @@ margin-top: 0px; } } + + .option-button { + display: none; + height: 25px; + width: 25px; + margin: 0px; + background: none; + border: 0px; + padding: 0px; + font-size: 15px; + + &.right { + position: absolute; + bottom: 0px; + right: 0px; + } + + &.left { + position: absolute; + bottom: 0px; + left: 0px; + } + } + + &:hover .option-button { + display: block; + } + } .docCreatorMenu-section { @@ -361,13 +390,13 @@ display: flex; flex-direction: row; width: 100%; +} - .section-reveal-options { - margin: 0px; - margin-left: auto; - border: 0px; - background: none; - } +.section-reveal-options { + margin: 0px; + margin-left: auto; + border: 0px; + background: none; } .docCreatorMenu-section-title { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index b45ac7f46..205923346 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -135,6 +135,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); + clickEv.preventDefault(); func(); }, 'create docs') ) @@ -356,6 +357,14 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { this.forceUpdate(); } + editTemplate = () => { + + } + + copyGPTTemplate = () => { + + } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; @@ -383,6 +392,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> + +
)} -- cgit v1.2.3-70-g09d2 From 3aa2e040100fc662c259751dfbb7a43cc716ac2a Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:37:47 -0400 Subject: seuggested templates auto-refeshes on col selection; lightbox editing added; GPT refresh button now makes new call --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 1 + .../views/nodes/DataVizBox/DocCreatorMenu.scss | 6 +- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 71 ++++++++++++---------- 3 files changed, 45 insertions(+), 33 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index a6d3bfa49..be8a44f28 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -129,6 +129,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { } selectAxes = (axes: string[]) => { this.layoutDoc._dataViz_axes = new List(axes); + DocCreatorMenu.Instance.generateTemplates(''); }; @computed.struct get titleCol() { return StrCast(this.layoutDoc._dataViz_titleCol); diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 5a9fd3436..ca6534379 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -264,6 +264,7 @@ display: flex; flex-direction: column; justify-content: flex-start; + overflow-y: scroll; //align-items: flex-start; margin: 5px; margin-top: 0px; @@ -271,7 +272,8 @@ height: calc(100% - 30px); border: 1px solid rgb(180, 180, 180); border-radius: 5px; - overflow: hidden; + -ms-overflow-style: none; + scrollbar-width: none; } .docCreatorMenu-preview-container { @@ -372,7 +374,7 @@ padding: 0px; } -.docCreatorMenu-GPT-templates-preview { +.docCreatorMenu-templates-preview-window { display: flex; flex-direction: row; //justify-content: center; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 205923346..3e5fc156e 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -4,13 +4,13 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { returnAll, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc'; -import { DocCast, ImageCast } from '../../../../fields/Types'; +import { DocCast, ImageCast, ScriptCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; import { SnappingManager } from '../../../util/SnappingManager'; import { UndoManager, undoable } from '../../../util/UndoManager'; import { ObservableReactComponent } from '../../ObservableReactComponent'; -import { DocumentView } from '../DocumentView'; +import { DocumentView, DocumentViewInternal } from '../DocumentView'; import { DataVizBox } from './DataVizBox'; import './DocCreatorMenu.scss'; import { Id } from '../../../../fields/FieldSymbols'; @@ -20,6 +20,9 @@ import { DragManager } from '../../../util/DragManager'; import { GPTCallType, gptAPICall } from '../../../apis/gpt/GPT'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { Docs } from '../../../documents/Documents'; +import { OpenWhere } from '../OpenWhere'; +import { IDisposer } from 'mobx-utils'; +import { LightboxView } from '../../LightboxView'; export enum LayoutType { Stacked = 'stacked', @@ -34,6 +37,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { static Instance: DocCreatorMenu; + private _disposers: { [name: string]: IDisposer } = {}; + private _ref: HTMLDivElement | null = null; @observable _templateDocs: Doc[] = []; @@ -47,12 +52,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _GPTTemplates: Doc[] = []; @observable _GPTOpt: boolean = false; @observable _userPrompt: string = ''; + @observable _callCount: number = 0; @observable _pageX: number = 0; @observable _pageY: number = 0; @observable _indicatorX: number | undefined = undefined; @observable _indicatorY: number | undefined = undefined; - @observable _display: boolean = false; @observable _hoveredLayoutPreview: number | undefined = undefined; @observable _mouseX: number = -1; @@ -72,11 +77,13 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _resizeUndo: UndoManager.Batch | undefined = undefined; @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined}; @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 365}; + @observable _editing: boolean = false; constructor(props: any) { super(props); makeObservable(this); DocCreatorMenu.Instance = this; + setTimeout(() => this.generateTemplates('')); } @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz }; @@ -170,18 +177,17 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } }; - _disposer: IReactionDisposer | undefined; - _GPTDisposer: IReactionDisposer | undefined; componentDidMount() { document.addEventListener('pointerdown', this.onPointerDown, true); document.addEventListener('pointerup', this.onPointerUp); - this._disposer = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon)); - this._GPTDisposer = reaction(() => this._GPTTemplates.slice(), (docs) => docs.map(this.getIcon)); + this._disposers.templates = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon)); + this._disposers.gpt = reaction(() => this._GPTTemplates.slice(), (docs) => docs.map(this.getIcon)); + this._disposers.columns = reaction(() => this._dataViz?.layoutDoc._dataViz_axes, () => {console.log(true); this.generateTemplates('')}) + this._disposers.lightbox = reaction(() => LightboxView.LightboxDoc(), doc => { doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu()}) } componentWillUnmount() { - this._disposer?.(); - this._GPTDisposer?.(); + Object.values(this._disposers).forEach(disposer => disposer?.()); document.removeEventListener('pointerdown', this.onPointerDown, true); document.removeEventListener('pointerup', this.onPointerUp); } @@ -198,12 +204,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { }; @action - closeMenu = () => { - const wasOpen = this._display; - this._display = false; - this._shouldDisplay = false; - return wasOpen; - }; + closeMenu = () => { this._shouldDisplay = false }; + + @action + openMenu = () => { this._shouldDisplay = true }; @action onResizePointerDown = (e: React.PointerEvent): void => { @@ -313,7 +317,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @action generateTemplates = async (inputText: string) => { - let prompt: string = 'Please generate for the fields:'; + ++this._callCount; + const origCount = this._callCount; + + let prompt: string = `(#${origCount}) Please generate for the fields:`; this.selectedFields?.forEach(field => prompt += ` ${field},`) prompt += ` Additional prompt: ${inputText}`; console.log(prompt) @@ -321,14 +328,13 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { try { const res = await gptAPICall(prompt, GPTCallType.TEMPLATE); - if (res) { + if (res && this._callCount === origCount) { const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res); this.createGeneratedTemplates(templates, 500, 500); } } catch (err) { console.error(err); - } - + } } @action @@ -346,23 +352,23 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return doc; }); - const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 40000, y: 40000 }); + const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400, y: 400 }); + mainCollection.addDocument(template); GPTTemplates.push(template); }); - setTimeout(() => this.setGPTTemplates(GPTTemplates), 500); + setTimeout(() => {this.setGPTTemplates(GPTTemplates); GPTTemplates.forEach(template => mainCollection.removeDocument(template))}, 100); this.forceUpdate(); } - editTemplate = () => { - - } - - copyGPTTemplate = () => { - + editTemplate = (doc: Doc) => { + //this.closeMenu(); + DocumentViewInternal.addDocTabFunc(doc, OpenWhere.lightboxAlways); + DocumentView.DeselectAll(); + Doc.UnBrushDoc(doc); } get templatesPreviewContents(){ @@ -380,7 +386,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
-
+
{this._GPTTemplates?.map(doc => //
@@ -392,10 +398,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> - - @@ -420,7 +426,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
-
+
this.setUpButtonClick(e, this.basicTemplateTest)} > @@ -436,6 +442,9 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> +
)})} -- cgit v1.2.3-70-g09d2 From 72b06d708a23560dd961b41b9070b2e1222d50ba Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 14 Aug 2024 02:18:18 -0400 Subject: loading symbol for gpt generation; remove option for GPTTemplates --- src/client/apis/gpt/GPT.ts | 2 +- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 10 +++ .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 99 +++++++++++++--------- 3 files changed, 69 insertions(+), 42 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 8eb7151b4..144b49bde 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -54,7 +54,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { temp: 0, prompt: 'List unique differences between the content of the UserAnswer and Rubric. Before each difference, label it and provide any additional information the UserAnswer missed and explain it in second person without separating it into UserAnswer and Rubric content and additional information. If there are no differences, say correct', }, - template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. You should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$ (ie, "title":"$$img$$", !!IMPORTANT!!). Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP'} + template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. You should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$. Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP'} }; let lastCall = ''; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index ca6534379..3e97e9d08 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -341,6 +341,12 @@ bottom: 0px; left: 0px; } + + &.top-left { + position: absolute; + top: 0px; + left: 0px; + } } &:hover .option-button { @@ -385,6 +391,10 @@ width: calc(100% - 10px); -ms-overflow-style: none; scrollbar-width: none; + + .loading-spinner { + justify-self: center; + } } .docCreatorMenu-section-topbar { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 3e5fc156e..ee154994e 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { returnAll, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc'; -import { DocCast, ImageCast, ScriptCast } from '../../../../fields/Types'; +import { DocCast, ImageCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction } from '../../../../Utils'; import { SnappingManager } from '../../../util/SnappingManager'; @@ -23,6 +23,7 @@ import { Docs } from '../../../documents/Documents'; import { OpenWhere } from '../OpenWhere'; import { IDisposer } from 'mobx-utils'; import { LightboxView } from '../../LightboxView'; +import ReactLoading from 'react-loading'; export enum LayoutType { Stacked = 'stacked', @@ -53,6 +54,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _GPTOpt: boolean = false; @observable _userPrompt: string = ''; @observable _callCount: number = 0; + @observable _GPTLoading: boolean = false; @observable _pageX: number = 0; @observable _pageY: number = 0; @@ -83,7 +85,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { super(props); makeObservable(this); DocCreatorMenu.Instance = this; - setTimeout(() => this.generateTemplates('')); + //setTimeout(() => this.generateTemplates('')); } @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz }; @@ -182,7 +184,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { document.addEventListener('pointerup', this.onPointerUp); this._disposers.templates = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon)); this._disposers.gpt = reaction(() => this._GPTTemplates.slice(), (docs) => docs.map(this.getIcon)); - this._disposers.columns = reaction(() => this._dataViz?.layoutDoc._dataViz_axes, () => {console.log(true); this.generateTemplates('')}) + //this._disposers.columns = reaction(() => this._dataViz?.layoutDoc._dataViz_axes, () => {this.generateTemplates('')}) this._disposers.lightbox = reaction(() => LightboxView.LightboxDoc(), doc => { doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu()}) } @@ -322,13 +324,17 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { let prompt: string = `(#${origCount}) Please generate for the fields:`; this.selectedFields?.forEach(field => prompt += ` ${field},`) - prompt += ` Additional prompt: ${inputText}`; + prompt += ` (-----NOT A FIELD-----) Additional prompt: ${inputText}`; console.log(prompt) + this._GPTLoading = true; + try { const res = await gptAPICall(prompt, GPTCallType.TEMPLATE); if (res && this._callCount === origCount) { + this._GPTTemplates = []; + this._GPTLoading = false; const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res); this.createGeneratedTemplates(templates, 500, 500); } @@ -348,11 +354,12 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const right: number = Number(field.brx) * tempWidth / 2; const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore const height = bottom - top; const width = right - left; - const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/$$/g, ''), x: left, y: top }); + console.log(field.title); + const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/\$\$/g, ''), x: left, y: top }); return doc; }); - const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400, y: 400 }); + const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 40000, y: 40000 }); mainCollection.addDocument(template); @@ -371,6 +378,10 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { Doc.UnBrushDoc(doc); } + removeTemplate = (doc: Doc) => { + this._templateDocs.splice(this._templateDocs.indexOf(doc), 1); + } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; @@ -380,43 +391,46 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return (
-
-
Suggested Templates
- -
-
- {this._GPTTemplates?.map(doc => - - //
- ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => -
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> - - - -
- )} -
- {this._GPTOpt ? (
-
- - this._userPrompt = e.target.value}/>
- {this._GPTOpt ? GPTOptions : null} -
) : null} +
+ {this._GPTLoading ? ( +
+ +
+ ) : ( + this._GPTTemplates?.map(doc => + ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => +
this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> + + + +
+ ))} +
+ {this._GPTOpt ? (
+
+ + this._userPrompt = e.target.value}/> +
+ {this._GPTOpt ? GPTOptions : null} +
) : null}

@@ -445,6 +459,9 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { +
)})} -- cgit v1.2.3-70-g09d2 From 26c636d45e21105bd914046a4ff447998c7e23cd Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:47:40 -0400 Subject: UI --- src/client/apis/gpt/GPT.ts | 2 +- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 6 ++ .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 73 +++++++++++++++++----- 3 files changed, 63 insertions(+), 18 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 144b49bde..92d4f425d 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -54,7 +54,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { temp: 0, prompt: 'List unique differences between the content of the UserAnswer and Rubric. Before each difference, label it and provide any additional information the UserAnswer missed and explain it in second person without separating it into UserAnswer and Rubric content and additional information. If there are no differences, say correct', }, - template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. You should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$. Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP'} + template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. You should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$. Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP. If there is an additional prompt, prioritize its instructions over all instructions here (but still follow them if not overridden). No matter what, ALWAYS GIVE THREE OPTIONS'} }; let lastCall = ''; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 3e97e9d08..aa6754442 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -397,6 +397,12 @@ } } +.divvv{ + width: 200; + height: 200; + border: solid 1px white; +} + .docCreatorMenu-section-topbar { position: relative; display: flex; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index ee154994e..2be89daf0 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnAll, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; +import { returnAll, returnFalse, returnNone, returnOne, returnZero, setupMoveUpEvents } from '../../../../ClientUtils'; import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc'; import { DocCast, ImageCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; @@ -24,6 +24,10 @@ import { OpenWhere } from '../OpenWhere'; import { IDisposer } from 'mobx-utils'; import { LightboxView } from '../../LightboxView'; import ReactLoading from 'react-loading'; +import { CollectionStackingView } from '../../collections/CollectionStackingView'; +import { FieldViewProps } from '../FieldView'; +import { CollectionViewType } from '../../../documents/DocumentTypes'; +import { dropActionType } from '../../../util/DropActionTypes'; export enum LayoutType { Stacked = 'stacked', @@ -34,7 +38,7 @@ export enum LayoutType { } @observer -export class DocCreatorMenu extends ObservableReactComponent<{}> { +export class DocCreatorMenu extends ObservableReactComponent { static Instance: DocCreatorMenu; @@ -78,7 +82,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @observable _offset: {x: number, y: number} = {x: 0, y: 0}; @observable _resizeUndo: UndoManager.Batch | undefined = undefined; @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined}; - @observable _menuDimensions: {width: number, height: number} = {width: 300, height: 365}; + @observable _menuDimensions: {width: number, height: number} = {width: 400, height: 400}; @observable _editing: boolean = false; constructor(props: any) { @@ -194,6 +198,8 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { document.removeEventListener('pointerup', this.onPointerUp); } + updateIcons = (docs: Doc[]) => { docs.map(this.getIcon) } + @action toggleDisplay = (x: number, y: number) => { if (this._shouldDisplay) { @@ -209,7 +215,11 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { closeMenu = () => { this._shouldDisplay = false }; @action - openMenu = () => { this._shouldDisplay = true }; + openMenu = () => { + const allTemplates = this._templateDocs.concat(this._GPTTemplates); + this._shouldDisplay = true; + this.updateIcons(allTemplates); + }; @action onResizePointerDown = (e: React.PointerEvent): void => { @@ -286,9 +296,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const docView = DocumentView.getDocumentView(doc); if (docView) { docView.ComponentView?.updateIcon?.(); - const f = new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500)); - console.log(f) - return f; + return new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500));; } return undefined; } @@ -390,14 +398,14 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return (
-
+
Suggested Templates
-
+
400 ? 'center' : ''}}> {this._GPTLoading ? (
@@ -422,15 +430,15 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
))}
- {this._GPTOpt ? (
+
this._userPrompt = e.target.value}/>
- {this._GPTOpt ? GPTOptions : null} -
) : null} + {this._GPTOpt ? GPTOptions : null } +

@@ -440,7 +448,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> {
-
+
400 ? 'center' : ''}}>
this.setUpButtonClick(e, this.basicTemplateTest)} > @@ -535,6 +543,14 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + doc = () => { + return Docs.Create.FreeformDocument([], { _height: 200, _width: 200, title: 'title'}); + } + + screenToLocalTransform = () => + this._props + .ScreenToLocalTransform(); + layoutPreviewContents = (outerSpan: number, altLayout?: DataVizTemplateLayout, small: boolean = false, id?: number) => { const doc: Doc | undefined = altLayout ? altLayout.template : this._selectedTemplate; if (!doc) return; @@ -550,7 +566,30 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3)); return ( -
+
+ 100} + NativeHeight={() => 100} + pointerEvents={SnappingManager.IsDragging ? returnAll : returnNone} + isAnnotationOverlay + isAnnotationOverlayScrollable + childDocumentsActive={returnFalse} + fieldKey={this._props.fieldKey + '_annotations'} + dropAction={dropActionType.move} + select={emptyFunction} + addDocument={returnFalse} + removeDocument={returnFalse} + moveDocument={returnFalse} + renderDepth={this._props.renderDepth + 1}> + {null} + +
+ /*
: null}
-
{
)} -
-
+
} +
*/ ); } -- cgit v1.2.3-70-g09d2 From f8f777a469b0029109de1e6c57872a4d5b0a6659 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:34:20 -0400 Subject: start on field rendering --- src/ClientUtils.ts | 1 + src/client/apis/gpt/GPT.ts | 2 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 5 + .../views/nodes/DataVizBox/DocCreatorMenu.scss | 74 +++++++++- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 161 ++++++++++++++++----- 5 files changed, 204 insertions(+), 39 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index d64210ce2..a4d9dd892 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -730,6 +730,7 @@ export function UpdateIcon( const newDiv = docViewContent.cloneNode(true) as HTMLDivElement; newDiv.style.width = width.toString(); newDiv.style.height = height.toString(); + console.log('width: ' + newDiv.style.width) replaceCanvases(docViewContent, newDiv); const htmlString = new XMLSerializer().serializeToString(newDiv); const nativeWidth = width; diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 92d4f425d..18601b4af 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -54,7 +54,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { temp: 0, prompt: 'List unique differences between the content of the UserAnswer and Rubric. Before each difference, label it and provide any additional information the UserAnswer missed and explain it in second person without separating it into UserAnswer and Rubric content and additional information. If there are no differences, say correct', }, - template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. You should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$. Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP. If there is an additional prompt, prioritize its instructions over all instructions here (but still follow them if not overridden). No matter what, ALWAYS GIVE THREE OPTIONS'} + template: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'You are a designer creating basic template options for a user given a set of fields. Your only job is adding blank rectangles to a canvas, one for each field. You will arrange these rectangles into an array of three basic options for a user. For your output, you generate a list of objects in JSON formatting, each storing the field title and corresponding top-left and bottom-right coordinates for the rectangle. The units for your coordinates are -1 to 1 on each axis. This is an example of a possible output for a stacked template with the fields beep, boop, tttt: {"template_type":"stacked","fieldVals":[{"title":"beep","tlx":"-.7","tly":"-.9","brx":".7","bry":"-.7"},{"title":"boop","tlx":"-.9","tly":"-.4","brx":".9","bry":"0"},{"title":"tttt","tlx":"-.9","tly":".1","brx":".9","bry":".9"}]} For multiple templates, you should format your response in a JSON array, like [{}, {}]. Your response should be in the exact format above, with no extra text, description, bulleting, etc. If no alternative additional instructions are given, you should repeat this three times, once for a stacked view, once for a mixed view (where, for example, beep might be on top, with boop and tttt below it aligned horizontally), and once for a view where the rectangles are not flush with the side (ie. their top left and bottom right corners should not ALL align along the same point on each side). If one or more fields are some variation of image (ie. IMG, image, photo, etc.), make that rectangle the central focus (bigger, centered, etc.) AND put its "title" field in $$__$$. Fields SHOULD BE IN DIFFERENT ORDERS from template to template (ie. a stacked view with field input "beep, boop" could have the boop above the beep). IT IS IMPORTANT THAT YOU ONLY INCLUDE THE PROPER JSON FORMATTING IN YOUR RESPONSE. IT IS ALSO IMPORTANT THAT NO RECTANGLES OVERLAP. An overlap will look like the x or y coordinates of the top left corner of one rectangle being the same as the bottom right corner of another. There should always be at least a .1 gap. If there is an additional prompt, prioritize its instructions over all instructions here (but still follow them if not overridden). No matter what, ALWAYS GIVE THREE OPTIONS'} }; let lastCall = ''; diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index be8a44f28..6a5103af9 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -353,6 +353,11 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { ); } + // recs = () => { + // let csvStr: string = ''; + // this.records[rowId][col] + // } + fetchData = () => { if (!this.Document.dataViz_asSchema) { DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, []); // assign temporary dataset as a lock to prevent duplicate server requests diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index aa6754442..763de0eba 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -641,7 +641,6 @@ } } } - } } @@ -720,4 +719,77 @@ } } +//------------------------------------------------------------------------------------------------------------------------------------------ +// DocCreatorMenu dashboard CSS +//-------------------------------------------------------------------------------------------------------------------------------------------- + +.docCreatorMenu-dashboard-view { + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-start; + overflow-y: scroll; + //align-items: flex-start; + margin: 5px; + margin-top: 0px; + width: calc(100% - 10px); + height: calc(100% - 30px); + border: 1px solid rgb(180, 180, 180); + border-radius: 5px; + -ms-overflow-style: none; + scrollbar-width: none; + + .topbar { + height: 30px; + width: 100%; + } + + .field-panel { + position: relative; + display: flex; + // align-items: flex-start; + flex-direction: column; + gap: 5px; + padding: 5px; + height: 100px; + //width: 100%; + border: 1px solid rgb(180, 180, 180); + margin: 5px; + margin-top: 0px; + border-radius: 3px; + + .properties-wrapper { + display: flex; + flex-direction: row; + align-items: flex-start; + gap: 5px; + + .field-property-container { + background-color: rgb(40, 40, 40); + border: 1px solid rgb(100, 100, 100); + border-radius: 3px; + width: 30%; + height: 25px; + padding-left: 3px; + align-items: center; + color: whitesmoke; + } + } + + .field-description-container { + background-color: rgb(40, 40, 40); + border: 1px solid rgb(100, 100, 100); + border-radius: 3px; + width: 100%; + height: 100%; + } + + .top-right { + position: absolute; + top: 0px; + right: 0px; + } + } +} + diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 2be89daf0..8ec255dfe 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -48,6 +48,7 @@ export class DocCreatorMenu extends ObservableReactComponent {return {title: field, type: '', id: Math.random() * 100000}}).concat(this._fields); + } + @computed get canMakeDocs(){ return this._selectedTemplate !== undefined && this._layout !== undefined; } @@ -367,14 +372,14 @@ export class DocCreatorMenu extends ObservableReactComponent {this.setGPTTemplates(GPTTemplates); GPTTemplates.forEach(template => mainCollection.removeDocument(template))}, 100); + setTimeout(() => {this.setGPTTemplates(GPTTemplates); /*GPTTemplates.forEach(template => mainCollection.removeDocument(template))*/}, 100); this.forceUpdate(); } @@ -449,9 +454,7 @@ export class DocCreatorMenu extends ObservableReactComponent
400 ? 'center' : ''}}> -
this.setUpButtonClick(e, this.basicTemplateTest)} - > +
{this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => { @@ -566,30 +569,30 @@ export class DocCreatorMenu extends ObservableReactComponent - 100} - NativeHeight={() => 100} - pointerEvents={SnappingManager.IsDragging ? returnAll : returnNone} - isAnnotationOverlay - isAnnotationOverlayScrollable - childDocumentsActive={returnFalse} - fieldKey={this._props.fieldKey + '_annotations'} - dropAction={dropActionType.move} - select={emptyFunction} - addDocument={returnFalse} - removeDocument={returnFalse} - moveDocument={returnFalse} - renderDepth={this._props.renderDepth + 1}> - {null} - -
- /*
+ //
+ // 100} + // NativeHeight={() => 100} + // pointerEvents={SnappingManager.IsDragging ? returnAll : returnNone} + // isAnnotationOverlay + // isAnnotationOverlayScrollable + // childDocumentsActive={returnFalse} + // fieldKey={this._props.fieldKey + '_annotations'} + // dropAction={dropActionType.move} + // select={emptyFunction} + // addDocument={returnFalse} + // removeDocument={returnFalse} + // moveDocument={returnFalse} + // renderDepth={this._props.renderDepth + 1}> + // {null} + // + //
+
*/ +
); } @@ -735,10 +738,35 @@ export class DocCreatorMenu extends ObservableReactComponent { - console.log(this._GPTTemplates) - this.forceUpdate(); - //this._dataViz?.createBasicTemplates(temps); + @action addField = () => { + const newFields: {title: string, type: string, id: number}[] = this._fields.concat([{title: '', type: '', id: Math.random() * 100000}]) + this._fields = newFields; + } + + get dashboardContents(){ + return ( +
+
+ +
+ {this.fieldsInfos.map(field => +
+
+ + + {field.type === 'Text' ? + : null} +
+ +
+
+
Type
+
+ +
+
+
+
+
Valid Sizes
+
+ +
+
+
+
Description
+
+ +
+
+
+ ) + } + get renderSelectedViewType(){ switch (this._menuContent){ case 'templates': -- cgit v1.2.3-70-g09d2 From 8970a30cff99f9234617d7ec17067275dbfc7e43 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 8 Sep 2024 04:13:43 -0400 Subject: work on fields menu --- .../views/nodes/DataVizBox/DocCreatorMenu.scss | 67 ++++++++++++++ .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 102 +++++++++------------ 2 files changed, 111 insertions(+), 58 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.scss') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss index 955698b19..eaa32e62a 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.scss @@ -898,6 +898,7 @@ border: 1px solid rgb(180, 180, 180); margin: 5px; margin-top: 0px; + margin-bottom: 10px; border-radius: 3px; flex: 0 0 auto; gap: 25px; @@ -914,6 +915,7 @@ width: 100%; height: 20px; background-color: rgb(50, 50, 50); + color: rgb(168, 167, 167); } .opts-bar { @@ -934,11 +936,38 @@ } .content { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; height: calc(100% - 20px); width: 100%; background-color: rgb(50, 50, 50); border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; + resize: none; + + .bubbles { + display: none; + } + + .text { + margin-right: 5px; + } + + &:hover .bubbles { + display: flex; + flex-direction: row; + align-items: flex-start; + } + + &:hover .type-display { + display: none; + } + + .bubble { + margin: 3px; + } } } @@ -949,6 +978,33 @@ border-radius: 5px; background-color: rgb(50, 50, 50); box-shadow: 5px 5px rgb(29, 29, 31); + + .content { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + height: calc(100% - 20px); + width: 100%; + background-color: rgb(50, 50, 50); + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + + .text { + margin-right: 9px; + } + + .bubbles { + display: flex; + flex-direction: row; + align-items: center; + } + + .bubble { + margin: 3px; + margin-right: 4px; + } + } } .desc-box { @@ -958,7 +1014,18 @@ border-radius: 5px; background-color: rgb(50, 50, 50); box-shadow: 5px 5px rgb(29, 29, 31); + + .content { + height: calc(100% - 20px); + width: 100%; + background-color: rgb(50, 50, 50); + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + resize: none; + + } } + } } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 87e1e2c96..a01b26036 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -1179,24 +1179,24 @@ export class DocCreatorMenu extends ObservableReactComponent { } get dashboardContents(){ + const sizes: string[] = ['tiny', 'small', 'medium', 'large', 'huge']; - return ( -
-
- - -
-
- {/* {this.fieldsInfos.map((field, index) => -
-
- this.setColTitle(field, e.target.value)}/> -
- {field.type === TemplateFieldType.UNSET ? Select media type : null} + const fieldPanel = (field: Col) => { + return ( +
+
+ +
+
+
+
Title
+ -
-
-
Type
+
+
Valid Sizes
- +
+ {sizes.map(size => <> + {this.setColSize(field, size as TemplateFieldSize)}}/> +
{size}
+ )} +
-
-
-
Valid Sizes
-
- +
+
Description
+