diff options
author | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-07-15 01:38:38 -0400 |
---|---|---|
committer | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-07-15 01:38:38 -0400 |
commit | e0dbe3a59d2e1e61fda951c250ef8d43cc0ccd3d (patch) | |
tree | 5bbe51881b68f9277a08812b30e1c450ab851119 /src | |
parent | 5e619c3f2491ee78297ac00329bb9c0a11132e6e (diff) |
layout options/preview progress
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu.scss | 14 | ||||
-rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 250 |
2 files changed, 174 insertions, 90 deletions
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<HTMLDivElement, Doc>; @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 ( <div className='docCreatorMenu-option-container'> <div className='docCreatorMenu-option-title config layout-config'> {title} </div> - <input className='docCreatorMenu-input config layout-config'/> + <input onInput={(e) => func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/> </div> ); } - switch (this._selectedLayout) { + switch (this._layout.type) { case LayoutType.Row: case LayoutType.Column: return ( <div className='docCreatorMenu-configuration-bar'> - {optionInput('Y Margin:')} - {optionInput('X Margin:')} + {optionInput('Y Margin:', this.updateYMargin)} + {optionInput('X Margin:', this.updateXMargin)} </div> ); case LayoutType.Grid: return ( <> <div className='docCreatorMenu-configuration-bar'> - {optionInput('Y Margin:')} - {optionInput('X Margin:')} + {optionInput('Y Margin:', this.updateYMargin)} + {optionInput('X Margin:', this.updateXMargin)} </div> <div className='docCreatorMenu-configuration-bar no-gap'> <div className='docCreatorMenu-option-title config dimensions'> Dimensions: </div> - <input className='docCreatorMenu-input config dimensions left'/> + <input className='docCreatorMenu-input config dimensions left' onInput={(e) => {this.updateDimensions('x', e.currentTarget.value); this.forceUpdate()}}/> <div className='docCreatorMenu-option-title spacer small'>x</div> - <input className='docCreatorMenu-input config dimensions right'/> + <input className='docCreatorMenu-input config dimensions right' onInput={(e) => this.updateDimensions('y', e.currentTarget.value)}/> </div> </> ); @@ -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 ( - <div className='docCreatorMenu-layout-preview-window'> + <div + className='docCreatorMenu-layout-preview-window' + style={{ + gridTemplateColumns: `repeat(${this.columnsCount}, ${scaledWidth}px)`, + gridTemplateRows: `repeat(${this.rowsCount}, ${scaledHeight}px)`, + rowGap: `${this._layout.yMargin}px`, + columnGap: `${this._layout.xMargin}px` + }}> + {this.docsToRender.map(num => + <div + className='docCreatorMenu-layout-preview-item' + style={{ + width: scaledWidth, + height: scaledHeight, + }} + > + {num} + </div> + )} </div> ); @@ -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<{}> { <div className='docCreatorMenu-menu-container'> <div className='docCreatorMenu-option-container layout'> <div className='docCreatorMenu-dropdown-hoverable'> - <div className="docCreatorMenu-option-title">{this._selectedLayout ? this._selectedLayout.toUpperCase() : 'Choose Layout'}</div> + <div className="docCreatorMenu-option-title">{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}</div> <div className="docCreatorMenu-dropdown-content"> {layoutOption(LayoutType.Stacked)} {layoutOption(LayoutType.Grid)} @@ -270,7 +340,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'}/> </button> </div> - {this._selectedLayout ? this.layoutConfigOptions: null} + {this._layout.type ? this.layoutConfigOptions: null} {this._layoutPreview ? this.layoutPreviewContents : null} {selectionBox(100, 30, 'Repeat:', undefined, repeatOptions.map(num => <option onPointerDown={e => this._templateInfo.repeat = num}>{`${num}x`}</option>))} </div> @@ -279,79 +349,61 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { render() { return ( - <div - className="docCreatorMenu-cont" - ref={r => 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 : - <> - <div - className='docCreatorMenu-menu' - onPointerDown={e => - 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} - > - <button - className='docCreatorMenu-menu-button' - onPointerDown={e => - setupMoveUpEvents( - this, - e, - returnFalse, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - runInAction(() => this._menuContent = this._menuContent === 'templates' ? 'options' : 'templates'); - }, 'create docs') - ) - } - > - <FontAwesomeIcon icon={this._menuContent === 'templates' ? 'bars' : 'table-cells'}/> - </button> - <button - className='docCreatorMenu-menu-button right' + <div className='docCreatorMenu'> + {!this._shouldDisplay ? undefined : + <div + className="docCreatorMenu-cont" + ref={r => this._ref = r} + style={{ + display: '', + left: this._pageX, + top: this._pageY, + width: 300, + height: 400, + background: SnappingManager.userBackgroundColor, + color: SnappingManager.userColor, + }}> + <div + className='docCreatorMenu-menu' onPointerDown={e => setupMoveUpEvents( this, e, - returnFalse, + (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(); - if (!this._selectedTemplate) return; - const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate}; - this._dataViz?.createDocsFromTemplate(templateInfo); - }, 'make docs') + }, 'drag menu') ) - }> - <FontAwesomeIcon icon={'plus'}/> - </button> - <button - className='docCreatorMenu-menu-button close-menu' + } + onPointerMove={e => this.onPointerMove(e)} + onPointerUp={() => this._dragging = false} + > + <button + className='docCreatorMenu-menu-button' + onPointerDown={e => + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + runInAction(() => this._menuContent = this._menuContent === 'templates' ? 'options' : 'templates'); + }, 'create docs') + ) + } + > + <FontAwesomeIcon icon={this._menuContent === 'templates' ? 'bars' : 'table-cells'}/> + </button> + <button + className='docCreatorMenu-menu-button right' onPointerDown={e => setupMoveUpEvents( this, @@ -360,17 +412,35 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); - this.closeMenu(); - }, 'close menu') + if (!this._selectedTemplate) return; + const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate}; + this._dataViz?.createDocsFromTemplate(templateInfo); + }, 'make docs') ) }> - <FontAwesomeIcon icon={'minus'}/> - </button> - </div> - <hr className='docCreatorMenu-menu-hr'/> - {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} - </> - } + <FontAwesomeIcon icon={'plus'}/> + </button> + <button + className='docCreatorMenu-menu-button close-menu' + onPointerDown={e => + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + this.closeMenu(); + }, 'close menu') + ) + }> + <FontAwesomeIcon icon={'minus'}/> + </button> + </div> + <hr className='docCreatorMenu-menu-hr'/> + {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} + </div> + } </div> ) } |