From e9bc998554515ecbe86f7d00b01d3cf5d2048b6e Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Thu, 3 Apr 2025 03:36:07 -0400
Subject: Firefly integration and some UI changes

---
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   | 213 ++++++++++++++-------
 1 file changed, 149 insertions(+), 64 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index 6d37f8f0f..0c5ae58a3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -31,6 +31,8 @@ import { TemplateField, ViewType } from './TemplateFieldTypes/TemplateField';
 import { Template } from './Template';
 import { TemplateFieldSize, TemplateFieldType, TemplateLayouts } from './TemplateBackend';
 import { TemplateManager } from './TemplateManager';
+import { DrawingFillHandler } from '../../../smartdraw/DrawingFillHandler';
+import { CgPathIntersect } from 'react-icons/cg';
 
 export enum LayoutType {
     FREEFORM = 'Freeform',
@@ -72,7 +74,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
     // eslint-disable-next-line no-use-before-define
     static Instance: DocCreatorMenu;
 
-    private DEBUG_MODE: boolean = false;
+    private DEBUG_MODE: boolean = true;
     private _disposers: { [name: string]: IDisposer } = {};
     private _ref: HTMLDivElement | null = null;
     private templateManager: TemplateManager;
@@ -91,6 +93,12 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
     @observable _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.FREEFORM, yMargin: 10, xMargin: 10, columns: 3, repeat: 0 };
     @observable _savedLayouts: DataVizTemplateLayout[] = [];
     @observable _expandedPreview: Doc | undefined = undefined;
+    @observable _variationsTab: boolean = false;
+    @observable _numVarsToGenerate: number = 3;
+    @observable _loadingVariants: boolean = false;
+    @observable _currentVariations: Doc[] = [];
+    @observable _variationPrompt: string = 'Use this template to generate an empty baseball card template.';
+    _previewWindow: HTMLDivElement | null = null;
 
     @observable _suggestedTemplates: Template[] = [];
     @observable _suggestedTemplatePreviews: { doc: Doc; template: Template }[] = [];
@@ -129,6 +137,10 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
         this.templateManager = new TemplateManager(TemplateLayouts.allTemplates);
     }
 
+    setContainerRef: React.LegacyRef<HTMLDivElement> = (node) => {
+        this._previewWindow = node;
+    };
+
     @action setDataViz = (dataViz: DataVizBox) => {
         this._dataViz = dataViz;
         this._selectedTemplate = undefined;
@@ -493,6 +505,42 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
         this.forceUpdate();
     };
 
+    @action setVariationTab = (open: boolean) => {
+        this._variationsTab = 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);
+        }
+    }
+
+    generateVariations = async (onDoc: Doc): Promise<Doc[]> => {
+        this._loadingVariants = true;
+        this.variationDocss = [];
+        const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
+
+        const clone: Doc = (await Doc.MakeClone(onDoc)).clone;
+        mainCollection.addDocument(clone);
+        clone.x = 10000;
+        clone.y = 10000;
+
+        await DrawingFillHandler.drawingToImage(clone, 100, this._variationPrompt, undefined, this)
+
+        this._loadingVariants = false;
+
+        return this.variationDocss;
+    }
+
+    @observable variationDocss: Doc[] = []
+
+    @action addVariationDoc = (doc: Doc) => {
+        this.variationDocss.push(doc);
+        const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
+        mainCollection.addDocument(doc);
+        doc.x = 10000;
+        doc.y = 10000;
+    }
+
     generateGPTImage = async (prompt: string): Promise<string | undefined> => {
         try {
             const res = await gptImageCall(prompt);
@@ -768,31 +816,71 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
         this._expandedPreview = template?.doc; //Docs.Create.FreeformDocument([doc], { _height: NumListCast(doc._height)[0], _width: NumListCast(doc._width)[0], title: ''});
     };
 
+    @action setVariationPrompt = (prompt: string) => {
+        this._variationPrompt = prompt;
+    }
+
     get editingWindow() {
         const rendered = !this._expandedPreview ? null : (
-            <div className="docCreatorMenu-expanded-template-preview">
-                <DocumentView
-                    Document={this._expandedPreview}
-                    isContentActive={emptyFunction}
-                    addDocument={returnFalse}
-                    moveDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    PanelWidth={() => this._menuDimensions.width - 10}
-                    PanelHeight={() => this._menuDimensions.height - 60}
-                    ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
-                    renderDepth={5}
-                    whenChildContentsActiveChanged={emptyFunction}
-                    focus={emptyFunction}
-                    styleProvider={DefaultStyleProvider}
-                    addDocTab={DocumentViewInternal.addDocTabFunc}
-                    pinToPres={() => undefined}
-                    childFilters={returnEmptyFilter}
-                    childFiltersByRanges={returnEmptyFilter}
-                    searchFilterDocs={returnEmptyDoclist}
-                    fitContentsToBox={returnFalse}
-                    fitWidth={returnFalse}
-                />
-            </div>
+             <>
+                 <div className="docCreatorMenu-expanded-template-preview" ref={this.setContainerRef}>
+                     { this._previewWindow ? <DocumentView
+                         Document={this._expandedPreview}
+                         isContentActive={emptyFunction}
+                         addDocument={returnFalse}
+                         moveDocument={returnFalse}
+                         removeDocument={returnFalse}
+                         PanelWidth={() => this._previewWindow?.clientWidth ?? 1000 - 10}
+                         PanelHeight={() => this._previewWindow?.clientHeight ?? 1000 - 60}
+                         ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
+                         renderDepth={5}
+                         whenChildContentsActiveChanged={emptyFunction}
+                         focus={emptyFunction}
+                         styleProvider={DefaultStyleProvider}
+                         addDocTab={DocumentViewInternal.addDocTabFunc}
+                         pinToPres={() => undefined}
+                         childFilters={returnEmptyFilter}
+                         childFiltersByRanges={returnEmptyFilter}
+                         searchFilterDocs={returnEmptyDoclist}
+                         fitContentsToBox={returnFalse}
+                         fitWidth={returnFalse}
+                     /> : null
+                     }
+                 </div>
+                 { this._variationsTab ? 
+                     <div className="docCreatorMenu-section">
+                        <div className="docCreatorMenu-section-topbar">
+                            <div className="docCreatorMenu-section-title" style={{color: 'white'}}>Variations</div>
+                                <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'dashboard')))}>
+                                    <FontAwesomeIcon icon="gear" />
+                                </button>
+                            </div>
+                            <div className="docCreatorMenu-templates-preview-window">
+                                {this._currentVariations.map(variant => 
+                                    <div className="docCreatorMenu-preview-window">
+                                        {this.docPreview(variant)}
+                                    </div>
+                                )}
+                            </div>
+                            <div className="docCreatorMenu-variation-prompt-input">
+                                <textarea
+                                    className="docCreatorMenu-variation-prompt-input-textbox"
+                                    onChange={e => this.setVariationPrompt(e.target.value)}
+                                    defaultValue={''}
+                                    placeholder={'Enter a custom prompt here (optional)'}
+                                />
+                                <button className="docCreatorMenu-menu-button" 
+                                    onPointerDown={e => this.setUpButtonClick(e, async () => {
+                                        this._currentVariations = await this.generateVariations(this._currEditingTemplate?.getRenderedDoc()!);
+                                    })
+                                }>
+                                    <FontAwesomeIcon icon="arrows-rotate" />
+                                </button>
+                            </div>
+                     </div>
+                 : null
+                 }
+             </>
         );
 
         return (
@@ -813,50 +901,46 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                         }>
                         <FontAwesomeIcon icon="minimize" />
                     </button>
-                    <button
-                        className="docCreatorMenu-menu-button section-reveal-options top-right-lower"
-                        onPointerDown={e =>
-                            this.setUpButtonClick(e, () => {
-                                this._currEditingTemplate?.printFieldInfo();
-                                /*this._currEditingTemplate?.resetToBase();*/ this.setExpandedView(this._currEditingTemplate);
-                            })
-                        }>
-                        <FontAwesomeIcon icon="arrows-rotate" color="white" />
+                    <button className="docCreatorMenu-menu-button section-reveal-options top-right" onPointerDown={e => this.setUpButtonClick(e, async () => {
+                         if (!this._currEditingTemplate) return;
+                            this.setVariationTab(!this._variationsTab);
+                         })}>
+                         <FontAwesomeIcon icon="lightbulb" />
                     </button>
                 </div>
             </div>
         );
     }
 
+    docPreview = (doc: Doc | undefined) =>
+        !doc ? null : (
+            <DocumentView
+                Document={doc}
+                isContentActive={emptyFunction} // !!! should be return false
+                addDocument={returnFalse}
+                moveDocument={returnFalse}
+                removeDocument={returnFalse}
+                PanelWidth={() => this._menuDimensions.height * .3}
+                PanelHeight={() => this._menuDimensions.height * .3}
+                ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
+                renderDepth={1}
+                whenChildContentsActiveChanged={emptyFunction}
+                focus={emptyFunction}
+                styleProvider={DefaultStyleProvider}
+                addDocTab={this._props.addDocTab}
+                pinToPres={() => undefined}
+                childFilters={returnEmptyFilter}
+                childFiltersByRanges={returnEmptyFilter}
+                searchFilterDocs={returnEmptyDoclist}
+                fitContentsToBox={returnFalse}
+                fitWidth={returnFalse}
+                hideDecorations={true}
+            />
+        );
+
     get templatesPreviewContents() {
         const GPTOptions = <div></div>;
 
-        const previewDoc = (doc: Doc | undefined, template: Template) =>
-            !doc ? null : (
-                <DocumentView
-                    Document={doc}
-                    isContentActive={emptyFunction} // !!! should be return false
-                    addDocument={returnFalse}
-                    moveDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    PanelWidth={() => (this._selectedTemplate === template ? 104 : 111)}
-                    PanelHeight={() => (this._selectedTemplate === template ? 104 : 111)}
-                    ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
-                    renderDepth={1}
-                    whenChildContentsActiveChanged={emptyFunction}
-                    focus={emptyFunction}
-                    styleProvider={DefaultStyleProvider}
-                    addDocTab={this._props.addDocTab}
-                    pinToPres={() => undefined}
-                    childFilters={returnEmptyFilter}
-                    childFiltersByRanges={returnEmptyFilter}
-                    searchFilterDocs={returnEmptyDoclist}
-                    fitContentsToBox={returnFalse}
-                    fitWidth={returnFalse}
-                    hideDecorations={true}
-                />
-            );
-
         //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
 
         return (
@@ -864,8 +948,8 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                 {this._expandedPreview ? (
                     this.editingWindow
                 ) : (
-                    <div>
-                        <div className="docCreatorMenu-section" style={{ height: this._GPTOpt ? 200 : 200 }}>
+                    <div className="docCreatorMenu-templates-displays">
+                         <div className="docCreatorMenu-section">
                             <div className="docCreatorMenu-section-topbar">
                                 <div className="docCreatorMenu-section-title">Suggested Templates</div>
                                 <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'dashboard')))}>
@@ -892,6 +976,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                                                 onPointerDown={e =>
                                                     this.setUpButtonClick(e, () => {
                                                         this.setExpandedView(template);
+                                                        this.forceUpdate();
                                                     })
                                                 }>
                                                 <FontAwesomeIcon icon="magnifying-glass" color="white" />
@@ -899,7 +984,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                                             <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.addUserTemplate(template))}>
                                                 <FontAwesomeIcon icon="plus" color="white" />
                                             </button>
-                                            {previewDoc(template.getRenderedDoc(), template)}
+                                            {this.docPreview(template.getRenderedDoc())}
                                         </div>
                                     ))
                                 )}
@@ -946,7 +1031,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                                         <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.removeUserTemplate(template))}>
                                             <FontAwesomeIcon icon="minus" color="white" />
                                         </button>
-                                        {previewDoc(template.getRenderedDoc(), template)}
+                                        {this.docPreview(template.getRenderedDoc())}
                                     </div>
                                 ))}
                             </div>
@@ -1396,4 +1481,4 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
             </div>
         );
     }
-}
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

