diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx | 193 |
1 files changed, 193 insertions, 0 deletions
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 |