From 4219c751c0f984fac6e5995c1ab955a8d63a28cd Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Sun, 11 May 2025 21:18:55 -0400
Subject: many changes to firefly UI (options added) and starting work on
 finalizing conditionals

---
 .../DocCreatorMenu/Menu/TemplateEditingWindow.tsx  | 160 ++++++++++++++-------
 1 file changed, 110 insertions(+), 50 deletions(-)

(limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx')

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
index 0434d0ccb..4ff509d73 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, reaction, runInAction } from "mobx";
+import { action, makeAutoObservable, makeObservable, observable, reaction, runInAction } from "mobx";
 import React from "react";
 import { returnFalse, returnEmptyFilter, returnTrue } from "../../../../../../ClientUtils";
 import { emptyFunction } from "../../../../../../Utils";
@@ -16,93 +16,77 @@ import { ObservableReactComponent } from "../../../../ObservableReactComponent";
 import { IDisposer } from "mobx-utils";
 import { ImageField } from "../../../../../../fields/URLField";
 import { DocCreatorMenuButton } from "./DocCreatorMenuButton";
+import { TbHistory } from "react-icons/tb";
 
-interface TemplateEditingWindowProps {
+export type FireflyStructureOptions = {
+    numVariations: number;
+    temperature: number;
+    useStyleRef: boolean;
+}
+
+interface FireflyVariationsTabProps {
     menu: DocCreatorMenu;
     template: Template;
 }
 
 @observer
-export class TemplateEditingWindow extends ObservableReactComponent<TemplateEditingWindowProps> {
+export class FireflyVariationsTab extends ObservableReactComponent<FireflyVariationsTabProps> {
 
-    private fireflyPrompt: string = 'Use this template to generate an empty baseball card template.';
-    private previewWindow: HTMLDivElement | null = null;
-    private disposers: { [name: string]: IDisposer } = {};
-    private promptInput: HTMLTextAreaElement | null = null;
+    private prompt: string = 'Use this template to generate an empty baseball card template.';
+
+    @observable private promptInput: HTMLTextAreaElement | null = null;
 
     @observable _loading: boolean = false;
     @observable _variationsTabOpen: boolean = false;
     @observable _variationURLs: string[] = [];
-    @observable _variations: Template[] = [];
-
-    componentDidMount(): void {
-        this.disposers.windowDimensions = reaction(() => 
-            this._props.menu._resizing, 
-            () => { this.forceUpdate() }, 
-            { fireImmediately: true }
-            );
-    }
-
-    componentWillUnmount() {
-        Object.values(this.disposers).forEach(disposer => disposer?.());
-    }
-
-    setPromptInputRef: React.LegacyRef<HTMLTextAreaElement> = (node) => {
-        this.promptInput = node;
-        this.forceUpdate();
-    }
 
-    setContainerRef: React.LegacyRef<HTMLDivElement> = (node) => {
-        this.previewWindow = node;
-        this.forceUpdate();
-    }
+    @observable private fireflyOptions: FireflyStructureOptions = {numVariations: 3, temperature: 0, useStyleRef: false};
 
-    @action setVariationTab = (open: boolean) => {
-        this._variationsTabOpen = open;
-        if (this.previewWindow && open) {
-            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * .6);
-        } else if (this.previewWindow && !open) {
-            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * 5/3);
-        }
-        this.forceUpdate();
+    constructor(props: FireflyVariationsTabProps) {
+        super(props);
+        makeObservable(this);
     }
 
     generateVariations = async () => {
         this._props.menu._variations = [];
         this._loading = true;
-        this._variationURLs = await this._props.menu.generateVariations(this._props.template.clone(false).getRenderedDoc()!, this.fireflyPrompt);
+        const doc: Doc = this._props.template.clone(false).getRenderedDoc()!;
+        this._variationURLs = await this._props.menu.generateVariations(doc, this.prompt, this.fireflyOptions);
         this._variationURLs.forEach(url => {
             const newTemplate: Template = this._props.template.clone(true);
             this._props.menu._variations.push(newTemplate);
         });
-        this._loading = false;
         setTimeout(() => {
             this._variationURLs.forEach((url, i) => {
                 this._props.menu._variations[i].setImageAsBackground(url, true);
             });
-            this.forceUpdate();
+            this._loading = false;
         });
     }
 
-    get fireflyVariationsTab() {
+    setPromptInputRef: React.LegacyRef<HTMLTextAreaElement> = (node) => {
+        this.promptInput = node;
+    }
 
+    render() {
         return (
-            <>
+            <div className='docCreatorMenu-editing-firefly-section'>
                 <div className="docCreatorMenu-option-divider full no-margin-bottom"/>
                 <TemplatePreviewGrid
                     menu={this._props.menu}
                     title={'Generate Variations'}
                     loading={this._loading}
+                    styles={'scrolling'}
                     templates={this._props.menu._variations}
                     optionsButtonOpts={['gear', () => {}]}
                     previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]}
                 />
-                <div className="docCreatorMenu-section">
-                    <div className="docCreatorMenu-variation-prompt-input">
+                <div className="docCreatorMenu-firefly-options">
+                    <div className="docCreatorMenu-variation-prompt-row">
                         <textarea
                             className="docCreatorMenu-variation-prompt-input-textbox"
                             ref={this.setPromptInputRef}
-                            onChange={e => this.fireflyPrompt = e.target.value}
+                            onChange={e => this.prompt = e.target.value}
                             onInput={() => {
                                 if (this.promptInput !== null) {
                                     this.promptInput.style.height = 'auto';
@@ -114,13 +98,84 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit
                         />
                         <DocCreatorMenuButton icon={'arrows-rotate'} styles={'border'} function={this.generateVariations}/>
                     </div>
-                    <div className='docCreatorMenu-variation-options-container'>
-
-                    </div>
+                        <nav className="options‑menu">
+                            <div className="menu‑item switch">
+                                <input type="checkbox" checked={this.fireflyOptions.useStyleRef} 
+                                    onChange={(e) => runInAction(() => this.fireflyOptions.useStyleRef = e.target.checked)}
+                                />
+                                <span className="slider round"></span>
+                                <span className="firefly-option-label">Use template as style guide</span>
+                            </div>
+                            <div className="menu‑item">
+                                <span className="firefly-option-label">Variations</span>
+                                <input type="range" id="variations" 
+                                    min="1" 
+                                    max="5" 
+                                    value={this.fireflyOptions.numVariations} 
+                                    onChange={(e) => runInAction(() => this.fireflyOptions.numVariations = Number(e.target.value))}
+                                />
+                                <span className="value" id="varVal">{this.fireflyOptions.numVariations}</span>
+                            </div>
+                            <div className="menu‑item">
+                                <span className="firefly-option-label">Temperature</span>
+                                <input type="range" id="temperature" 
+                                    min="1" 
+                                    max="100" 
+                                    value={this.fireflyOptions.temperature} 
+                                    onChange={(e) => runInAction(() => this.fireflyOptions.temperature = Number(e.target.value))}
+                                />
+                                <span className="value" id="tempVal">{this.fireflyOptions.temperature}</span>
+                            </div>
+                        </nav>
                 </div>
-            </>
+            </div>
         )
     }
+}
+
+interface TemplateEditingWindowProps {
+    menu: DocCreatorMenu;
+    template: Template;
+}
+
+@observer
+export class TemplateEditingWindow extends ObservableReactComponent<TemplateEditingWindowProps> {
+
+    private disposers: { [name: string]: IDisposer } = {};
+
+    @observable private previewWindow: HTMLDivElement | null = null;
+
+    @observable _variationsTabOpen: boolean = false;
+
+    constructor(props: TemplateEditingWindowProps) {
+        super(props);
+        makeObservable(this);
+    }
+
+    componentDidMount(): void {
+        this.disposers.windowDimensions = reaction(() => 
+            this._props.menu._resizing, 
+            () => { this.forceUpdate() }, 
+            { fireImmediately: true }
+            );
+    }
+
+    componentWillUnmount() {
+        Object.values(this.disposers).forEach(disposer => disposer?.());
+    }
+
+    setContainerRef: React.LegacyRef<HTMLDivElement> = (node) => {
+        this.previewWindow = node;
+    }
+
+    @action setVariationTab = (open: boolean) => {
+        this._variationsTabOpen = open;
+        if (this.previewWindow && open) {
+            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * .6);
+        } else if (this.previewWindow && !open) {
+            this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * 5/3);
+        }
+    }
    
     get renderedDocPreview(){
         const doc: Doc = this._props.template.getRenderedDoc() as unknown as Doc;
@@ -158,7 +213,11 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit
                 <div className="docCreatorMenu-expanded-template-preview">
                     <div className="top-panel"/>
                     {this.renderedDocPreview}
-                    {this._variationsTabOpen ? this.fireflyVariationsTab : null}
+                    {this._variationsTabOpen ? <FireflyVariationsTab
+                        menu={this._props.menu}
+                        template={this._props.template}
+                    />
+                     : null}
                     <div className="right-buttons-panel">
                         <DocCreatorMenuButton icon={'minimize'} function={() => {
                                 if (this._props.template === this._props.menu._selectedTemplate) {
@@ -167,6 +226,7 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit
                                 this._props.menu.setExpandedView(undefined);
                             }}/>
                         <DocCreatorMenuButton icon={'lightbulb'} function={() => this.setVariationTab(!this._variationsTabOpen)}/>
+                        <DocCreatorMenuButton icon={'arrow-rotate-backward'} function={() => { this._props.menu.setExpandedView(this._props.template); this.forceUpdate(); }}/>
                     </div>
                 </div>
             </div>
-- 
cgit v1.2.3-70-g09d2

