aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu')
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ExpandedTemplatePreview.tsx0
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/FieldOptionsScreen.tsx0
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx6
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx193
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateRenderPreviewWindow.tsx346
5 files changed, 542 insertions, 3 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ExpandedTemplatePreview.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ExpandedTemplatePreview.tsx
deleted file mode 100644
index e69de29bb..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ExpandedTemplatePreview.tsx
+++ /dev/null
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/FieldOptionsScreen.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/FieldOptionsScreen.tsx
deleted file mode 100644
index e69de29bb..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/FieldOptionsScreen.tsx
+++ /dev/null
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
index cb87e9b47..3eaed79b6 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
@@ -227,9 +227,9 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit
: null}
<div className="right-buttons-panel">
<DocCreatorMenuButton icon={'minimize'} function={() => {
- if (this._props.template === this._props.menu._selectedTemplate) {
- this._props.menu.updateRenderedPreviewCollection(this._props.template);
- }
+ // if (this._props.template === this._props.menu._selectedTemplate) {
+ // this._props.menu.updateRenderedPreviewCollection(this._props.template);
+ // }
this._props.menu.setExpandedView(undefined);
}}/>
<DocCreatorMenuButton icon={'lightbulb'} function={() => this.setVariationTab(!this._variationsTabOpen)}/>
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx
new file mode 100644
index 000000000..beda45ac3
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx
@@ -0,0 +1,193 @@
+import { makeObservable, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { ObservableReactComponent } from "../../../../ObservableReactComponent";
+import { Col, DocCreatorMenu } from "../DocCreatorMenu";
+import React from "react";
+import { Conditional, TemplateManager } from "../Backend/TemplateManager";
+import { TemplateFieldType, TemplateFieldSize } from "../TemplateBackend";
+import { DocCreatorMenuButton } from "./DocCreatorMenuButton";
+
+interface TemplateMenuFieldOptionsProps {
+ menu: DocCreatorMenu;
+ templateManager: TemplateManager;
+}
+
+@observer
+export class TemplateMenuFieldOptions extends ObservableReactComponent<TemplateMenuFieldOptionsProps> {
+
+ @observable _collapsedCols: String[] = []; //any columns whose options panels are hidden
+
+ constructor(props: TemplateMenuFieldOptionsProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ @observable private _newCondCache: Record<string, Conditional> = {};
+
+ getParams = (title: string, parameters?: Conditional): Conditional => {
+ if (parameters) return parameters;
+
+ if (!this._newCondCache[title]) {
+ this._newCondCache[title] = observable<Conditional>({
+ field: title,
+ operator: '=',
+ condition: '',
+ target: 'Own',
+ attribute: '',
+ value: ''
+ });
+ }
+ return this._newCondCache[title];
+ };
+
+ conditionForm = (title: string, parameters?: Conditional, empty: boolean = false) => {
+
+ const contentFieldTitles = this._props.menu.fieldsInfos.filter(field => field.type !== TemplateFieldType.DATA).map(field => field.title).concat('Template');
+ var params: Conditional = this.getParams(title, parameters);
+
+ return (
+ <div className='form'>
+ <div className='form-row'>
+ <div className='form-row-plain-text'>If</div>
+ <div className='form-row-plain-text'>{title}</div>
+ <div className="operator-options-dropdown">
+ <span className="operator-dropdown-current">{params.operator ?? '='}</span>
+ <div className='operator-dropdown-option' onPointerDown={() => {params.operator = '='}}>{'='}</div>
+ </div>
+ <input
+ className="form-row-textarea"
+ onChange={e => runInAction(() => params.condition = e.target.value)}
+ placeholder='value'
+ value={params.condition}
+ />
+ <div className='form-row-plain-text'>then</div>
+ <div className="operator-options-dropdown">
+ <span className="operator-dropdown-current">{params.target ?? 'Own'}</span>
+ {contentFieldTitles.map(fieldTitle =>
+ <div className='operator-dropdown-option' onPointerDown={() => {params.target = fieldTitle}}>{fieldTitle === title ? 'Own' : fieldTitle}</div>
+ )}
+ </div>
+ <input
+ className="form-row-textarea"
+ onChange={e => runInAction(() => params.attribute = e.target.value)}
+ placeholder='attribute'
+ value={params.attribute}
+ />
+ <div className='form-row-plain-text'>{'becomes'}</div>
+ <input
+ className="form-row-textarea"
+ onChange={e => runInAction(() => params.value = e.target.value)}
+ placeholder='value'
+ value={params.value}
+ />
+ </div>
+ {empty ?
+ <DocCreatorMenuButton icon={'plus'} styles={'float-right border'} function={() => {
+ this._newCondCache[title] = observable<Conditional>({
+ field: title,
+ operator: '=',
+ condition: '',
+ target: 'Own',
+ attribute: '',
+ value: ''
+ });
+ this._props.templateManager.addFieldCondition(title, params);
+ }}/>
+ :
+ <DocCreatorMenuButton icon={'minus'} styles={'float-right border'} function={() => this._props.templateManager.removeFieldCondition(title, params)}/>
+ }
+ </div>
+ )
+ }
+
+ fieldPanel = (field: Col, id: number) => (
+ <div className="field-panel" key={id}>
+ <div className="top-bar" onPointerDown={e => this._props.menu.setUpButtonClick(e, runInAction(() => () => {
+ if (this._collapsedCols.includes(field.title)) {
+ this._collapsedCols = this._collapsedCols.filter(col => col !== field.title);
+ } else {
+ this._collapsedCols.push(field.title);
+ }
+ }))}>
+ <span className="field-title">{`${field.title} Field`}</span>
+ <DocCreatorMenuButton icon={'minus'} styles={'no-margin absolute-right'} function={() => this._props.menu.removeField(field)}/>
+ </div>
+ { this._collapsedCols.includes(field.title) ? null :
+ <>
+ <div className="opts-bar">
+ <div className="opt-box">
+ <div className="top-bar"> Title </div>
+ <textarea className="content" style={{ width: '100%', height: 'calc(100% - 20px)' }} value={field.title} placeholder={'Enter title'} onChange={e => this._props.menu.setColTitle(field, e.target.value)} />
+ </div>
+ <div className="opt-box">
+ <div className="top-bar"> Type </div>
+ <div className="content">
+ <span className="type-display">{
+ field.type === TemplateFieldType.TEXT ? 'Text Field'
+ : field.type === TemplateFieldType.VISUAL ? 'File Field'
+ : field.type === TemplateFieldType.DATA ? 'Data Field'
+ : ''
+ }</span>
+ <div className="bubbles">
+ <input className="bubble" type="radio" name="type" onClick={() => this._props.menu.setColType(field, TemplateFieldType.TEXT)} />
+ <div className="text">Text</div>
+ <input className="bubble" type="radio" name="type" onClick={() => this._props.menu.setColType(field, TemplateFieldType.VISUAL)} />
+ <div className="text">File</div>
+ <input className="bubble" type="radio" name="type" onClick={() => this._props.menu.setColType(field, TemplateFieldType.DATA)} />
+ <div className="text">Data</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ { field.type === TemplateFieldType.DATA ? null :
+ (<>
+ <div className="sizes-box">
+ <div className="top-bar"> Valid Sizes </div>
+ <div className="content">
+ <div className="bubbles">
+ {Object.values(TemplateFieldSize).map(size => (
+ <div key={field + size}>
+ <input className="bubble" type="checkbox" name="type" checked={field.sizes.includes(size)} onChange={e => this._props.menu.modifyColSizes(field, size, e.target.checked)} />
+ <div className="text">{size}</div>
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ <div className="desc-box">
+ <div className="top-bar"> Prompt </div>
+ <textarea
+ className="content"
+ onChange={e => this._props.menu.setColDesc(field, e.target.value)}
+ defaultValue={field.desc === this._props.menu._dataViz?.GPTSummary?.get(field.title)?.desc ? '' : field.desc}
+ placeholder={this._props.menu._dataViz?.GPTSummary?.get(field.title)?.desc ?? 'Add a description/prompt to help with template generation.'}
+ />
+ </div>
+ </>)
+ }
+ <div className="conditionals-section">
+ <span className="conditionals-title">Conditional Logic</span>
+ {this.conditionForm(field.title, undefined, true)}
+ {this._props.templateManager.conditionalFieldLogic[field.title]?.map(condition => this.conditionForm(condition.field, condition))}
+ </div>
+ </>
+ }
+ </div>
+ );
+
+
+
+ render() {
+ return (
+ <div className="docCreatorMenu-dashboard-view">
+ <div className="topbar">
+ <DocCreatorMenuButton icon={'plus'} function={this._props.menu.addField}/>
+ <DocCreatorMenuButton icon={'arrow-left'} styles={'float-right'} function={() => runInAction(() => (this._props.menu._menuContent = 'templates'))}/>
+ </div>
+ <div className="panels-container">{this._props.menu.fieldsInfos.map((field, i) => this.fieldPanel(field, i))}</div>
+ </div>
+ );
+ }
+
+
+} \ No newline at end of file
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateRenderPreviewWindow.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateRenderPreviewWindow.tsx
new file mode 100644
index 000000000..219152549
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateRenderPreviewWindow.tsx
@@ -0,0 +1,346 @@
+import { action, computed, makeObservable, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { ObservableReactComponent } from "../../../../ObservableReactComponent";
+import { DataVizTemplateLayout, DocCreatorMenu, LayoutType } from "../DocCreatorMenu";
+import React from "react";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { setupMoveUpEvents, returnFalse, returnEmptyFilter } from "../../../../../../ClientUtils";
+import { emptyFunction } from "../../../../../../Utils";
+import { undoable } from "../../../../../util/UndoManager";
+import ReactLoading from "react-loading";
+import { Doc, NumListCast, returnEmptyDoclist } from "../../../../../../fields/Doc";
+import { StrCast } from "../../../../../../fields/Types";
+import { DefaultStyleProvider } from "../../../../StyleProvider";
+import { DocumentView } from "../../../DocumentView";
+import { Transform } from "../../../../../util/Transform";
+import { Docs, DocumentOptions } from "../../../../../documents/Documents";
+import { Template } from "../Template";
+
+interface TemplatesRenderPreviewWindowProps {
+ menu: DocCreatorMenu;
+}
+
+@observer
+export class TemplatesRenderPreviewWindow extends ObservableReactComponent<TemplatesRenderPreviewWindowProps> {
+
+ @observable private _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.FREEFORM, yMargin: 10, xMargin: 10, columns: 0, repeat: 0 };
+
+ @observable private renderedDocs: Doc[] = [];
+ @observable private renderedDocCollection: Doc | undefined = undefined;
+
+ @observable private loading: boolean = false;
+
+ constructor(props: TemplatesRenderPreviewWindowProps) {
+ super(props);
+ makeObservable(this);
+ this.updateRenderedPreviewCollection();
+ }
+
+ @computed get canMakeDocs() {
+ return this._props.menu._selectedTemplate !== undefined && this._layout !== undefined;
+ }
+
+ @computed get docsToRender() {
+ if (this._props.menu.DEBUG_MODE) {
+ return [1, 2, 3, 4];
+ } else {
+ return NumListCast(this._props.menu._dataViz?.layoutDoc.dataViz_selectedRows);
+ }
+ }
+
+ @computed get rowsCount() {
+ switch (this._layout.type) {
+ case LayoutType.FREEFORM:
+ return Math.ceil(this.docsToRender.length / (this._layout.columns ?? 1)) ?? 0;
+ case LayoutType.CAROUSEL3D:
+ return 1.8;
+ default:
+ return 1;
+ }
+ }
+
+ @computed get columnsCount() {
+ switch (this._layout.type) {
+ case LayoutType.FREEFORM:
+ return this._layout.columns ?? 0;
+ case LayoutType.CAROUSEL3D:
+ return 3;
+ default:
+ return 1;
+ }
+ }
+
+ @action updateRenderedPreviewCollection = async () => {
+ this.loading = true;
+ this.renderedDocs = await this._props.menu.createDocsForPreview();
+ this.updateRenderedDocCollection();
+ };
+
+ /**
+ * Updates the preview that shows how all docs will be rendered in the chosen collection type.
+ @type the type of collection the docs should render to (ie. freeform, carousel, card)
+ */
+ updateRenderedDocCollection = () => {
+ if (!this.renderedDocs) return;
+
+ const collectionFactory = (): ((docs: Doc[], options: DocumentOptions) => Doc) => {
+ switch (this._layout.type) {
+ case LayoutType.CAROUSEL3D: return Docs.Create.Carousel3DDocument;
+ case LayoutType.FREEFORM: return Docs.Create.FreeformDocument;
+ case LayoutType.CARD: return Docs.Create.CardDeckDocument;
+ case LayoutType.MASONRY: return Docs.Create.MasonryDocument;
+ case LayoutType.CAROUSEL: return Docs.Create.CarouselDocument;
+ default: return Docs.Create.FreeformDocument;
+ } // prettier-ignore
+ };
+
+ const collection = collectionFactory()(this.renderedDocs, {
+ isDefaultTemplateDoc: true,
+ title: 'title',
+ backgroundColor: 'gray',
+ x: 200,
+ y: 200,
+ _width: 4000,
+ _height: 4000,
+ });
+
+ this.applyLayout(collection, this.renderedDocs);
+
+ this.renderedDocCollection = collection;
+
+ this.loading = false;
+
+ this.forceUpdate();
+ };
+
+ @action updateMargin = (input: string, xOrY: 'x' | 'y') => {
+ this._layout[`${xOrY}Margin`] = Number(input);
+ setTimeout(() => {
+ if (!this.renderedDocCollection || !this.renderedDocs) return;
+ this.applyLayout(this.renderedDocCollection, this.renderedDocs);
+ });
+ };
+
+ @action updateColumns = (input: string) => {
+ this._layout.columns = Number(input);
+ this.updateRenderedDocCollection();
+ };
+
+ applyLayout = (collection: Doc, docs: Doc[]) => {
+ const { horizontalSpan, verticalSpan } = this.previewInfo;
+ collection._height = verticalSpan;
+ collection._width = horizontalSpan;
+
+ const columns: number = this._layout.columns ?? this.columnsCount;
+ const xGap: number = this._layout.xMargin;
+ const yGap: number = this._layout.yMargin;
+ const startX: number = -Number(collection._width) / 2;
+ const startY: number = -Number(collection._height) / 2;
+ const docHeight: number = Number(docs[0]._height);
+ const docWidth: number = Number(docs[0]._width);
+
+ if (columns === 0 || docs.length === 0) {
+ return;
+ }
+
+ 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;
+ curX += docWidth + xGap;
+ ++docsChanged;
+ ++i;
+ }
+ i = 0;
+ curX = startX;
+ curY += docHeight + yGap;
+ }
+ };
+
+ @computed
+ get previewInfo() {
+ const docHeight: number = Number(this.renderedDocs[0]._height);
+ const docWidth: number = Number(this.renderedDocs[0]._width);
+ const layout = this._layout;
+ return {
+ docHeight: docHeight,
+ docWidth: docWidth,
+ horizontalSpan: (docWidth + layout.xMargin) * this.columnsCount - layout.xMargin,
+ verticalSpan: (docHeight + layout.yMargin) * this.rowsCount - layout.yMargin,
+ };
+ }
+
+ get layoutConfigOptions() {
+ const optionInput = (icon: string, func: (input: string) => void, def?: number, key?: string, noMargin?: boolean) => {
+ return (
+ <div className="docCreatorMenu-option-container small no-margin" key={key} style={{ marginTop: noMargin ? '0px' : '' }}>
+ <div className="docCreatorMenu-option-title config layout-config">
+ <FontAwesomeIcon icon={icon as IconProp} />
+ </div>
+ <input defaultValue={def} onInput={e => func(e.currentTarget.value)} className="docCreatorMenu-input config layout-config" />
+ </div>
+ );
+ };
+
+ switch (this._layout.type) {
+ case LayoutType.FREEFORM:
+ return (
+ <div className="docCreatorMenu-configuration-bar">
+ {optionInput('arrows-up-down', (input: string) => this.updateMargin(input, 'y'), this._layout.xMargin, '2')}
+ {optionInput('arrows-left-right', (input: string) => this.updateMargin(input, 'x'), this._layout.xMargin, '3')}
+ {optionInput('table-columns', this.updateColumns, this._layout.columns, '4', true)}
+ </div>
+ );
+ default:
+ break;
+ }
+ }
+
+ layoutPreviewContents = action(() => {
+ return this.loading ? (
+ <div className="docCreatorMenu-layout-preview-window-wrapper loading">
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ </div>
+ </div>
+ ) : !this.renderedDocCollection ? null : (
+ <div className="docCreatorMenu-layout-preview-window-wrapper">
+ <DocumentView
+ Document={this.renderedDocCollection}
+ isContentActive={emptyFunction}
+ addDocument={returnFalse}
+ moveDocument={returnFalse}
+ removeDocument={returnFalse}
+ PanelWidth={() => this._props.menu._menuDimensions.width - 80}
+ PanelHeight={() => this._props.menu._menuDimensions.height - 105}
+ ScreenToLocalTransform={() => new Transform(-this._props.menu._pageX - 5, -this._props.menu._pageY - 35, 1)}
+ renderDepth={5}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ styleProvider={DefaultStyleProvider}
+ addDocTab={this._props.menu._props.addDocTab}
+ pinToPres={() => undefined}
+ childFilters={returnEmptyFilter}
+ childFiltersByRanges={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ fitContentsToBox={returnFalse}
+ fitWidth={returnFalse}
+ hideDecorations={true}
+ />
+ </div>
+ );
+ });
+
+ selectionBox = (width: number, height: number, icon: string, specClass?: string, options?: JSX.Element[], manual?: boolean): JSX.Element => {
+ return (
+ <div className="docCreatorMenu-option-container">
+ <div className={`docCreatorMenu-option-title config ${specClass}`} style={{ width: width * 0.4, height: height }}>
+ <FontAwesomeIcon icon={icon as IconProp} />
+ </div>
+ {manual ? (
+ <input className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }} />
+ ) : (
+ <select className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }}>
+ {options}
+ </select>
+ )}
+ </div>
+ );
+ };
+
+ layoutOption = (option: LayoutType, optStyle?: object, specialFunc?: () => void) => {
+ return (
+ <div
+ className="docCreatorMenu-dropdown-option"
+ style={optStyle}
+ onPointerDown={e =>
+ this._props.menu.setUpButtonClick(e, () => {
+ specialFunc?.();
+ runInAction(() => {
+ this._layout.type = option;
+ this.updateRenderedDocCollection();
+ });
+ })
+ }>
+ {option}
+ </div>
+ );
+ };
+
+ get optionsMenuContents() {
+
+ const repeatOptions = [0, 1, 2, 3, 4, 5];
+
+ return (
+ <div className="docCreatorMenu-menu-container">
+ <div className="docCreatorMenu-option-container layout">
+ <div className="docCreatorMenu-dropdown-hoverable">
+ <div className="docCreatorMenu-option-title">{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}</div>
+ <div className="docCreatorMenu-dropdown-content">
+ {this.layoutOption(LayoutType.FREEFORM, undefined, () => {
+ if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length));
+ })}
+ {this.layoutOption(LayoutType.CAROUSEL)}
+ {this.layoutOption(LayoutType.CAROUSEL3D)}
+ {this.layoutOption(LayoutType.MASONRY)}
+ </div>
+ </div>
+ </div>
+ {this._layout.type ? this.layoutConfigOptions : null}
+ {this.layoutPreviewContents()}
+ {this.selectionBox(
+ 60,
+ 20,
+ 'repeat',
+ undefined,
+ repeatOptions.map(num => <option key={num} onPointerDown={() => (this._layout.repeat = num)}>{`${num}x`}</option>)
+ )}
+ <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();
+ //previous implementation deprecated; return later to add or scrap
+ return;
+ }, 'save layout')
+ )
+ }>
+ <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();
+ this.renderedDocCollection && this._props.menu.addRenderedCollectionToMainview(this.renderedDocCollection);
+ }, 'make docs')
+ )
+ }>
+ <FontAwesomeIcon icon="plus" />
+ </button>
+ </div>
+ </div>
+ );
+ }
+
+ render() { return this.optionsMenuContents }
+} \ No newline at end of file