diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx')
| -rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 130 |
1 files changed, 104 insertions, 26 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 67999fc39..fdf623150 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -40,6 +40,7 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { @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; + @observable _savedLayouts: DataVizTemplateLayout[] = []; @observable _pageX: number = 0; @observable _pageY: number = 0; @@ -193,6 +194,20 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { } } + @action updateSelectedSavedLayout = (layout: DataVizTemplateLayout) => { + this._layout.xMargin = layout.layout.xMargin; + this._layout.yMargin = layout.layout.yMargin; + this._layout.type = layout.layout.type; + this._layout.columns = layout.columns; + } + + isSelectedLayout = (layout: DataVizTemplateLayout) => { + return this._layout.xMargin === layout.layout.xMargin + && this._layout.yMargin === layout.layout.yMargin + && this._layout.type === layout.layout.type + && this._layout.columns === layout.columns; + } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; return ( @@ -203,13 +218,35 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { return (<div className='docCreatorMenu-preview-window' style={{ - background: this._selectedTemplate === info.doc ? Colors.MEDIUM_BLUE : '', + border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '', boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '' }} onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}> <img className='docCreatorMenu-preview-image' src={info.icon!.url.href.replace(".png", "_o.png")} /> </div> )})} + <div className='docCreatorMenu-preview-window empty'> + <FontAwesomeIcon icon='plus' color='rgb(160, 160, 160)'/> + </div> + </div> + ); + } + + get savedLayoutsPreviewContents(){ + return ( + <div className='docCreatorMenu-preview-container'> + {this._savedLayouts.map((layout, index) => + <div + className='docCreatorMenu-preview-window' + style={{ + border: this.isSelectedLayout(layout) ? `solid 3px ${Colors.MEDIUM_BLUE}` : '', + boxShadow: this.isSelectedLayout(layout) ? `0 0 15px rgba(68, 118, 247, .8)` : '' + }} + onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))} + > + {this.layoutPreviewContents(87, layout, false, true, index)} + </div> + )} </div> ); } @@ -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 ( - <div className='docCreatorMenu-layout-preview-window-wrapper'> - <div className='docCreatorMenu-zoom-button-container'> + <div className='docCreatorMenu-layout-preview-window-wrapper' id={String(id) ?? undefined}> + {!zoomOption ? null : <div className='docCreatorMenu-zoom-button-container'> <button className='docCreatorMenu-zoom-button' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= 1.25))}> @@ -283,15 +323,16 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= .75))}> <FontAwesomeIcon icon={'plus'}/> </button> - </div> + </div>} <div - className='docCreatorMenu-layout-preview-window' + id={String(id) ?? undefined} + className={`docCreatorMenu-layout-preview-window ${small ? 'small' : ''}`} style={{ - gridTemplateColumns: `repeat(${this.columnsCount}, ${scaledDown(docWidth)}px`, + gridTemplateColumns: `repeat(${altLayout ? altLayout.columns : this.columnsCount}, ${scaledDown(docWidth)}px`, gridTemplateRows: `${scaledDown(docHeight)}px`, gridAutoRows: `${scaledDown(docHeight)}px`, - rowGap: `${scaledDown(this._layout.yMargin)}px`, - columnGap: `${scaledDown(this._layout.xMargin)}px` + rowGap: `${scaledDown(layout.yMargin)}px`, + columnGap: `${scaledDown(layout.xMargin)}px` }}> {this._layout.type === LayoutType.Stacked ? <div @@ -365,32 +406,61 @@ export class DocCreatorMenu extends ObservableReactComponent<{}> { </div> </div> <button - className='docCreatorMenu-menu-button' + className='docCreatorMenu-menu-button preview-toggle' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreview = !this._layoutPreview))}> <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'}/> </button> </div> {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 => <option onPointerDown={e => this._layout.repeat = num}>{`${num}x`}</option>))} - <button - className='docCreatorMenu-create-docs-button' - style={{backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'rgb(180, 180, 180)'}} - onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction, + <hr className='docCreatorMenu-option-divider'/> + <div className='docCreatorMenu-general-options-container'> + <button + className='docCreatorMenu-save-layout-button' + onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); if (!this._selectedTemplate) return; - 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') + const layout: DataVizTemplateLayout = {template: this._selectedTemplate, layout: {type: this._layout.type, xMargin: this._layout.xMargin, yMargin:this._layout.yMargin, repeat: 0}, columns: this.columnsCount, rows: this.rowsCount, docsNumList: this.docsToRender}; + this._savedLayouts.push(layout); + }, 'make docs') ) }> - Create - </button> + <FontAwesomeIcon icon='floppy-disk'/> + </button> + <button + className='docCreatorMenu-create-docs-button' + style={{backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'solid 2px rgb(180, 180, 180)'}} + onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + if (!this._selectedTemplate) return; + 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') + ) + }> + <FontAwesomeIcon icon='plus'/> + </button> + </div> </div> ); } + 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<{}> { <FontAwesomeIcon icon={'minus'}/> </button> </div> - {this._menuContent === 'templates' ? this.templatesPreviewContents : this.optionsMenuContents} + {this.renderSelectedViewType} </div> </> } @@ -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 |
