aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx')
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx185
1 files changed, 185 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..f0e20837c
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateMenuFieldOptions.tsx
@@ -0,0 +1,185 @@
+import { action, makeObservable, observable } 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');
+ const 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={action(e => (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, i) => (
+ <div className="operator-dropdown-option" key={i} onPointerDown={() => (params.target = fieldTitle)}>
+ {fieldTitle === title ? 'Own' : fieldTitle}
+ </div>
+ ))}
+ </div>
+ <input className="form-row-textarea" onChange={action(e => (params.attribute = e.target.value))} placeholder="attribute" value={params.attribute} />
+ <div className="form-row-plain-text">{'becomes'}</div>
+ <input className="form-row-textarea" onChange={action(e => (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,
+ action(() => {
+ 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={action(() => (this._props.menu._menuContent = 'templates'))} />
+ </div>
+ <div className="panels-container">{this._props.menu.fieldsInfos.map((field, i) => this.fieldPanel(field, i))}</div>
+ </div>
+ );
+ }
+}