From 691fc130de706c691a42f7e87688c14102016ccc Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Tue, 29 Oct 2024 04:02:29 -0400
Subject: starting to integrate refactor with docreatormenu functionality

---
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx  | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx

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

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
new file mode 100644
index 000000000..890bc6f73
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -0,0 +1,23 @@
+import { Col } from "./DocCreatorMenu";
+import { FieldSettings } from "./FieldTypes/Field";
+import { Template } from "./Template";
+import { TemplateLayouts } from "./TemplateBackend";
+
+export class TemplateManager {
+
+    templates: Template[] = [];
+
+    constructor(templateSettings: FieldSettings[]) {
+        this.templates = this.initializeTemplates(templateSettings);
+    }
+
+    initializeTemplates = (templateSettings: FieldSettings[]): Template[] => {
+        const initializedTemplates: Template[] = [];
+        templateSettings.forEach(settings => initializedTemplates.push(new Template(settings)));
+        return initializedTemplates;
+    }
+
+    getValidTemplates = (cols: Col[]): Template[] => {
+        return this.templates.filter(template => template.isValidTemplate(cols));
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 58e97fd9a8c85c7e4df75aed17d914498680c190 Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Tue, 29 Oct 2024 16:25:30 -0400
Subject: no compile errors but probably 100 logical ones

---
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   | 131 ++++++---------------
 .../DocCreatorMenu/FieldTypes/DynamicField.tsx     |   5 +
 .../DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx |   2 +
 .../DocCreatorMenu/FieldTypes/StaticField.tsx      |   5 +
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx  |  12 ++
 5 files changed, 61 insertions(+), 94 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index 36264f886..46266883f 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -59,7 +59,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
     @observable _templateDocs: Doc[] = [];
     @observable _selectedTemplate: Doc | undefined = undefined;
-    @observable _columns: Col[] = [];
+    @observable _userCreatedColumns: Col[] = [];
     @observable _selectedCols: { title: string; type: string; desc: string }[] | undefined = [];
 
     @observable _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.GRID, yMargin: 0, xMargin: 0, repeat: 0 };
@@ -176,7 +176,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
                 return col;
             })
-            .concat(this._columns);
+            .concat(this._userCreatedColumns);
     }
 
     @computed get canMakeDocs() {
@@ -486,15 +486,15 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     @action addField = () => {
-        const newFields: Col[] = this._columns.concat([{ title: '', type: TemplateFieldType.UNSET, desc: '', sizes: [] }]);
-        this._columns = newFields;
+        const newFields: Col[] = this._userCreatedColumns.concat([{ title: '', type: TemplateFieldType.UNSET, desc: '', sizes: [] }]);
+        this._userCreatedColumns = newFields;
     };
 
     @action removeField = (field: { title: string; type: string; desc: string }) => {
         if (this._dataViz?.axes.includes(field.title)) {
             this._dataViz.selectAxes(this._dataViz.axes.filter(col => col !== field.title));
         } else {
-            const toRemove = this._columns.filter(f => f === field);
+            const toRemove = this._userCreatedColumns.filter(f => f === field);
             if (!toRemove) return;
 
             if (toRemove.length > 1) {
@@ -503,10 +503,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 }
             }
 
-            if (this._columns.length === 1) {
-                this._columns = [];
+            if (this._userCreatedColumns.length === 1) {
+                this._userCreatedColumns = [];
             } else {
-                this._columns.splice(this._columns.indexOf(toRemove[0]), 1);
+                this._userCreatedColumns.splice(this._userCreatedColumns.indexOf(toRemove[0]), 1);
             }
         }
     };
@@ -573,7 +573,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
      * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
      * @returns a doc containing the fully rendered template
      */
-    fillPresetTemplate = async (template: Template, assignments: { [field: string]: Col }): Promise<Doc> => {
+    applyGPTContentToTemplate = async (template: Template, assignments: { [field: string]: Col }): Promise<Template> => {
         const wordLimit = (size: TemplateFieldSize) => {
             switch (size) {
                 case TemplateFieldSize.TINY:
@@ -654,12 +654,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             return rendered;
         };
 
-        const fields: Field[] = [];
-
-        const autoLoadedFields = Object.entries(assignments).filter(([f, col]) => this._columns.includes(col));
-        const userCreatedFields: [string, Col][] = Object.entries(assignments).filter(a => !autoLoadedFields.includes(a));
-        const GPTTextCalls = autoLoadedFields.filter(([str, col]) => col.type === TemplateFieldType.TEXT);
-        const GPTIMGCalls = autoLoadedFields.filter(([str, col]) => col.type === TemplateFieldType.VISUAL);
+        const GPTTextCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.TEXT);
+        const GPTIMGCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.VISUAL);
 
         const stringifyGPTInfo = (calls: [string, Col][]): string => {
             let string: string = '*** COLUMN INFO:';
@@ -671,84 +667,24 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const GPTTextAssignment = stringifyGPTInfo(GPTTextCalls);
 
-        let fieldContent: string = '';
-
-        Object.entries(userCreatedFields).forEach(([fieldID, strAndCol]) => {
-            const field: Field = template.getFieldByID(Number(fieldID));
-            const col = strAndCol[1];
-
-            const doc = (col.type === TemplateFieldType.VISUAL ? FieldUtils.ImageField : FieldUtils.TextField)(
-                {
-                    tl: field.tl,
-                    br: field.br,
-                },
-                template.height,
-                template.width,
-                col.title,
-                col.defaultContent ?? '',
-                field.opts
-            );
-
-            fieldContent += `--- Field #${fieldID} (title: ${col.title}): ${col.defaultContent ?? ''} ---`;
-
-            fields.push(doc);
-        });
-
-        template.decorations.forEach(dec => {
-            console.log(dec);
-            const doc = FieldUtils.TextField(
-                {
-                    tl: dec.tl,
-                    br: dec.br,
-                },
-                template.height,
-                template.width,
-                '',
-                '',
-                dec.opts
-            );
-
-            fields.push(doc);
-        });
-
-        const createMainDoc = (): Doc => {
-            const main = Docs.Create.FreeformDocument(fields, {
-                _height: template.height,
-                _width: template.width,
-                title: template.title,
-                backgroundColor: template.opts.backgroundColor,
-                _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px',
-                borderWidth: template.opts.borderWidth,
-                borderColor: template.opts.borderColor,
-                x: 40000,
-                y: 40000,
-            });
-
-            const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
-            mainCollection.addDocument(main);
-
-            return main;
-        };
+        let fieldContent: string = this.templateManager.getContentSummary(template);
 
         const textCalls = await renderTextCalls();
         const imageCalls = await renderImageCalls();
 
-        textCalls.forEach(doc => {
-            fields.push(doc);
-        });
-        imageCalls.forEach(doc => {
-            fields.push(doc);
-        });
-
-        return createMainDoc();
+        return template;
     };
 
+    renderTemplates = (templates: Template[]) => {
+
+    }
+
     compileFieldDescriptions = (templates: Template[]): string => {
         let descriptions: string = '';
         templates.forEach(template => {
-            descriptions += `----------  NEW TEMPLATE TO INCLUDE: Description of template ${template.title}'s fields: `;
-            template.fields.forEach((field, index) => {
-                descriptions += `{Field #${index}: ${field.description}} `;
+            descriptions += `----------  NEW TEMPLATE TO INCLUDE: Description of template ${template.mainField.getTitle()}'s fields: `;
+            template.allFields.forEach(field => {
+                descriptions += `{Field #${field.getID}: ${field.getDescription}} `;
             });
         });
 
@@ -767,7 +703,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     @action
-    assignColsToFields = async (templates: TemplateDocInfos[], cols: Col[]): Promise<[TemplateDocInfos, { [field: number]: Col }][]> => {
+    assignColsToFields = async (templates: Template[], cols: Col[]): Promise<[Template, { [field: number]: Col }][]> => {
         const fieldDescriptions: string = this.compileFieldDescriptions(templates);
         const colDescriptions: string = this.compileColDescriptions(cols);
 
@@ -784,15 +720,22 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             const res = await gptAPICall(prompt, GPTCallType.TEMPLATE);
 
             if (res && this._callCount === origCount) {
-                const assignments: { [templateTitle: string]: { [field: string]: string } } = JSON.parse(res);
-                const brokenDownAssignments: [TemplateDocInfos, { [field: number]: Col }][] = [];
+                const assignments: { [templateTitle: string]: { [fieldID: string]: string } } = JSON.parse(res);
+                const brokenDownAssignments: [Template, { [fieldID: number]: Col }][] = [];
 
                 Object.entries(assignments).forEach(([tempTitle, assignment]) => {
-                    const template = TemplateLayouts.getTemplateByTitle(tempTitle);
+                    const template = templates.filter(template => template.mainField.getTitle() === tempTitle)[0];
                     if (!template) return;
                     const toObj = Object.entries(assignment).reduce(
-                        (a, [fieldNum, colTitle]) => {
-                            a[Number(fieldNum)] = this.getColByTitle(colTitle);
+                        (a, [fieldID, colTitle]) => {
+                            const col = this.getColByTitle(colTitle);
+                            if (!this._userCreatedColumns.includes(col)){ // do the following for any fields not added by the user; will change in the future, for now only GPT content works with user-added fields
+                                const field = template.getFieldByID(Number(fieldID));
+                                field.setContent(col.defaultContent ?? '', col.type === TemplateFieldType.VISUAL ? FieldContentType.IMAGE : FieldContentType.STRING);
+                                field.setTitle(col.title);
+                            } else {
+                                a[Number(fieldID)] = this.getColByTitle(colTitle);
+                            }
                             return a;
                         },
                         {} as { [field: number]: Col }
@@ -814,14 +757,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const cols = this.fieldsInfos;
         const templates = this.templateManager.getValidTemplates(cols);
 
-        const assignments: [TemplateDocInfos, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
+        const assignments: [Template, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
 
-        const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) => this.fillPresetTemplate(template, assignments));
+        const renderedTemplatePromises: Promise<Template>[] = assignments.map(([template, assignments]) => this.applyGPTContentToTemplate(template, assignments));
 
-        const renderedTemplates: Doc[] = await Promise.all(renderedTemplatePromises);
+        const renderedTemplates: Template[] = await Promise.all(renderedTemplatePromises);
 
         setTimeout(() => {
-            this.setGSuggestedTemplates(renderedTemplates);
+            this.setGSuggestedTemplates(renderedTemplates.map(template => template.mainField.renderedDoc()));
             this._GPTLoading = false;
         });
     };
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
index a55f44589..220d938ff 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
@@ -21,6 +21,7 @@ export class DynamicField implements Field {
         this.type = type;
         this.id = id;
         this.settings = settings;
+        if (settings.title) { this.title = settings.title };
         if (!parent) {
             this.parent = this;
             this.dimensions = {width: this.settings.br[0] - this.settings.tl[0], height: this.settings.br[1] - this.settings.tl[1], coord: {x: this.settings.tl[0], y: this.settings.tl[1]}};
@@ -51,6 +52,10 @@ export class DynamicField implements Field {
     get getID() { return this.id };
     get getViewType() { return this.type };
 
+    get getDescription(): string {
+        return this.settings.description ?? '';
+    }
+
     matches = (cols: Col[]): Array<number> => {
         return [];
     }
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
index aa1d1de33..feba6a8ef 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
@@ -10,6 +10,7 @@ export interface Field {
     getAllSubfields: Field[];
     getID: number;
     getViewType: ViewType;
+    getDescription: string;
     getTitle: () => string;
     setTitle: (title: string) => void;
     setupSubfields: () => Field[];
@@ -22,6 +23,7 @@ export type FieldSettings = {
     br: [number, number];
     opts: FieldOpts;
     viewType: ViewType;
+    title?: string;
     subfields?: FieldSettings[];
     types?: TemplateFieldType[];
     sizes?: TemplateFieldSize[];
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
index cd1008429..809b40520 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
@@ -23,6 +23,7 @@ export class StaticField {
 
     constructor(settings: FieldSettings, parent: Field, id: number) {
         this.settings = settings;
+        if (settings.title) { this.title = settings.title };
         this.id = id;
         this.parent = parent;
         this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions);
@@ -45,6 +46,10 @@ export class StaticField {
     get getID() { return this.id };
     get getViewType() { return ViewType.STATIC };
 
+    get getDescription(): string {
+        return this.settings.description ?? '';
+    }
+
     setContent = (newContent: string, type: FieldContentType) => { 
         this.content = newContent;
         this.contentType = type;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
index 890bc6f73..d47ae802c 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -17,6 +17,18 @@ export class TemplateManager {
         return initializedTemplates;
     }
 
+    /**
+     * Provides a text summary of content currently filled into a template, formatted for GPT analysis.
+     * @param template the template to be summarized
+     */
+    getContentSummary = (template: Template) => {
+        let summary: string = '';
+        template.contentFields.forEach(field => {
+            summary += `--- Field #${field.getID} (title: ${field.getTitle()}): ${field.getContent() ?? ''} ---`;
+        });
+        return summary;
+    }
+
     getValidTemplates = (cols: Col[]): Template[] => {
         return this.templates.filter(template => template.isValidTemplate(cols));
     }
-- 
cgit v1.2.3-70-g09d2


From 66fcb190ad52aa7e5fc7e0055fed392a569c1972 Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Tue, 29 Oct 2024 18:48:25 -0400
Subject: matching algorithm working

---
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx    |  4 +++-
 .../DocCreatorMenu/FieldTypes/DynamicField.tsx      | 15 +++++++--------
 .../DocCreatorMenu/FieldTypes/StaticField.tsx       | 16 ++++++++++------
 .../nodes/DataVizBox/DocCreatorMenu/Template.tsx    | 21 ++++++++++++++++-----
 .../DataVizBox/DocCreatorMenu/TemplateBackend.tsx   |  2 +-
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx   |  1 +
 6 files changed, 38 insertions(+), 21 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index 46266883f..a1de81fa3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -469,7 +469,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     testTemplate = async () => {
-        this.updateIcons(this._suggestedTemplates.slice());
+        
+        console.log(this.templateManager.templates);
+
         this.forceUpdate();
 
         // try {
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
index 220d938ff..f235d3218 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
@@ -7,7 +7,6 @@ import { FieldUtils } from "./FieldUtils";
 import { StaticField } from "./StaticField";
 
 export class DynamicField implements Field {
-    private type: ViewType;
     private subfields: Field[] = [];
 
     private id: number;
@@ -17,8 +16,7 @@ export class DynamicField implements Field {
     private parent: Field;
     private dimensions: FieldDimensions;
 
-    constructor(settings: FieldSettings, type: ViewType, id: number, parent?: Field) {
-        this.type = type;
+    constructor(settings: FieldSettings, id: number, parent?: Field) {
         this.id = id;
         this.settings = settings;
         if (settings.title) { this.title = settings.title };
@@ -50,7 +48,7 @@ export class DynamicField implements Field {
 
     get getDimensions() { return this.dimensions };
     get getID() { return this.id };
-    get getViewType() { return this.type };
+    get getViewType() { return this.settings.viewType };
 
     get getDescription(): string {
         return this.settings.description ?? '';
@@ -61,16 +59,17 @@ export class DynamicField implements Field {
     }
 
     setupSubfields = (): Field[] => {
+        const fields: Field[] = [];
         this.settings.subfields?.forEach(fieldSettings => {
             let field: Field;
             const dynamicType = fieldSettings.viewType;
 
-            if (dynamicType) { field = new DynamicField(fieldSettings, dynamicType, 0, this); }
+            if (dynamicType) { field = new DynamicField(fieldSettings, 0, this); }
 
             field = new StaticField(fieldSettings, this, 0);
-            this.subfields?.push(field);
+            fields.push(field);
         });
-        return [];
+        return fields;
     }
 
     getChildDimensions = (coords: { tl: [number, number]; br: [number, number] }): FieldDimensions => {
@@ -85,7 +84,7 @@ export class DynamicField implements Field {
     };
 
     renderedDoc = (): Doc => {
-        switch (this.type) {
+        switch (this.settings.viewType) {
             case ViewType.CAROUSEL3D:
                 const carouselDoc = Docs.Create.Carousel3DDocument([], {
                     title: this.title,
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
index 809b40520..0f3631858 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
@@ -44,7 +44,7 @@ export class StaticField {
 
     get getDimensions() { return this.dimensions };
     get getID() { return this.id };
-    get getViewType() { return ViewType.STATIC };
+    get getViewType() { return this.settings.viewType };
 
     get getDescription(): string {
         return this.settings.description ?? '';
@@ -63,10 +63,10 @@ export class StaticField {
         const fields: Field[] = [];
         this.settings.subfields?.forEach(fieldSettings => {
             let field: Field;
-            const dynamicType = fieldSettings.viewType;
+            const type = fieldSettings.viewType;
 
-            if (dynamicType) { 
-                field = new DynamicField(fieldSettings, dynamicType, 0, this); 
+            if (type === ViewType.FREEFORM || type === ViewType.CAROUSEL3D) { 
+                field = new DynamicField(fieldSettings, 0, this); 
             } else {
                 field = new StaticField(fieldSettings, this, 0);
             };
@@ -78,8 +78,12 @@ export class StaticField {
 
     matches = (cols: Col[]): number[] => {
         const colMatchesField = (col: Col) => {
-            return this.settings.sizes?.some(size => col.sizes?.includes(size)) && this.settings.types?.includes(col.type);
-        };
+            const isMatch: boolean = (
+                this.settings.sizes?.some(size => col.sizes?.includes(size)) 
+                && this.settings.types?.includes(col.type)) 
+                ?? false;
+            return isMatch;
+        }
 
         const matches: Array<number> = [];
 
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
index 486fe7f7e..708170359 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
@@ -24,33 +24,44 @@ export class Template {
     }
 
     setupMainField = (templateInfo: FieldSettings) => {
-        return new DynamicField(templateInfo, ViewType.FREEFORM, 0);
+        return new DynamicField(templateInfo, 0);
     }
 
     isValidTemplate = (cols: Col[]) => {
-        return this.maxMatches(this.getMatches(cols)) === this.contentFields.length;
+        const matches: number[][] = this.getMatches(cols);
+        const maxMatches: number = this.maxMatches(matches);
+        return maxMatches === this.contentFields.length;
     }
 
-    getMatches = (cols: Col[]) => {
-        const matches: number[][] = Array(this.contentFields.length)
+    getMatches = (cols: Col[]): number[][] => {
+        const numFields = this.contentFields.length;
+
+        if (cols.length !== numFields) return [];
+
+        const matches: number[][] = Array(numFields)
             .fill([])
             .map(() => []);
 
         this.contentFields.forEach((field, i) => {
-            matches[i].concat(field.matches(cols));
+            matches[i] = (field.matches(cols));
         });
 
         return matches;
     }
 
     maxMatches = (matches: number[][]) => {
+        if (matches.length === 0) return 0;
+
         const fieldsCt = this.contentFields.length;
         const used: boolean[] = Array(fieldsCt).fill(false);
         const mt: number[] = Array(fieldsCt).fill(-1);
 
+        console.log(matches, fieldsCt);
+
         const augmentingPath = (v: number): boolean => {
             if (used[v]) return false;
             used[v] = true;
+
             for (const to of matches[v]) {
                 if (mt[to] === -1 || augmentingPath(mt[to])) {
                     mt[to] = v;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
index 00eb8fab4..a23c3ba3d 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
@@ -17,7 +17,7 @@ export enum TemplateFieldSize {
 
 export class TemplateLayouts {
     public static get allTemplates(): FieldSettings[] {
-        return Object.values(TemplateLayouts).filter(value => typeof value === 'object' && value !== null && 'title' in value) as FieldSettings[];
+        return Object.values(TemplateLayouts);
     }
 
     public static FourField001: FieldSettings = {
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
index d47ae802c..535bd423f 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -30,6 +30,7 @@ export class TemplateManager {
     }
 
     getValidTemplates = (cols: Col[]): Template[] => {
+        console.log(this.templates.filter(template => template.isValidTemplate(cols)));
         return this.templates.filter(template => template.isValidTemplate(cols));
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From de18eecdbd0ac99cdc78aef2dd477e341c28df76 Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Tue, 29 Oct 2024 21:45:37 -0400
Subject: content is being filled into fields properly

---
 src/client/apis/gpt/GPT.ts                         |   2 +-
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   | 108 +++++++++------------
 .../DocCreatorMenu/FieldTypes/DynamicField.tsx     |   8 +-
 .../DocCreatorMenu/FieldTypes/StaticField.tsx      |   9 +-
 .../nodes/DataVizBox/DocCreatorMenu/Template.tsx   |   4 +-
 .../DataVizBox/DocCreatorMenu/TemplateBackend.tsx  |   5 +
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx  |   1 -
 7 files changed, 62 insertions(+), 75 deletions(-)

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

diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index d38e512bd..19f124bf7 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -66,7 +66,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = {
         prompt: 'List unique differences between the content of the UserAnswer and Rubric. Before each difference, label it and provide any additional information the UserAnswer missed and explain it in second person without separating it into UserAnswer and Rubric content and additional information. If there are no differences, say correct',
     },
     template: {
-        model: 'gpt-4o-mini',
+        model: 'gpt-4-turbo',
         maxTokens: 512,
         temp: 0.5,
         prompt: 'You will be given a list of field descriptions for multiple templates in the format {field #0: “description”}{field #1: “description”}{...}, and a list of column descriptions in the format {“title”: “description”}{...}. Your job is to match columns with fields based on their descriptions. Your output should be in the following JSON format: {“Template title”:{“#”: “title”, “#”: “title”, “#”: “title” …}, “Template title”:{“#”: “title”, “#”: “title”, “#”: “title” …}} where “Template title” represents the template,  # represents the field # and “title” the title of the column assigned to it. A filled out example might look like {“fivefield2”:{“0”:”Name”, “1”:”Image”, “2”:”Caption”, “3”:”Position”, “4”:”Stats”}, “fivefield3”:{0:”Image”, 1:”Name”, 2:”Caption”, 3:”Stats”, 4:”Position”}. Include one object for each template. IT IS VERY IMPORTANT THAT YOU ONLY INCLUDE TEXT IN THE FORMAT ABOVE, WITH NO ADDITIONS WHATSOEVER. Do not include extraneous ‘#’ characters, ‘column’ for columns, or ‘template’ for templates: ONLY THE TITLES AND NUMBERS. There should never be one column assigned to more than one field (ie. if the “name” column is assigned to field 1, it can’t be assigned to any other fields) . Do this for each template whose fields are described. The descriptions are as follows:',
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index a1de81fa3..405b32e8a 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -104,7 +104,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         makeObservable(this);
         DocCreatorMenu.Instance = this;
         this.templateManager = new TemplateManager(TemplateLayouts.allTemplates);
-        //setTimeout(() => this.generateTemplates(''));
     }
 
     @action setDataViz = (dataViz: DataVizBox) => {
@@ -264,7 +263,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     }
 
     updateIcons = (docs: Doc[]) => {
-        console.log('called')
         docs.map(this.getIcon);
     };
 
@@ -593,34 +591,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             }
         };
 
-        const renderTextCalls = async (): Promise<Doc[]> => {
-            const rendered: Doc[] = [];
-
-            if (GPTTextCalls.length) {
-                try {
-                    const prompt = fieldContent + GPTTextAssignment;
-
-                    const res = await gptAPICall(prompt, GPTCallType.FILL);
-
-                    if (res) {
-                        const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
-                        //console.log('assignments', GPTAssignments, 'assignment string', GPTAssignmentString, 'field content', fieldContent, 'response', res, 'assignments', assignments);
-                        Object.entries(assignments).forEach(([title, info]) => {
-                            const field: Field = template.getFieldByID(Number(info.number));
-                            const col = this.getColByTitle(title);
-
-                            field.setContent(info.content ?? '', FieldContentType.STRING);
-                            field.setTitle(col.title);
-                        });
-                    }
-                } catch (err) {
-                    console.log(err);
-                }
-            }
-
-            return rendered;
-        };
-
         const generateAndLoadImage = async (fieldNum: string, col: Col, prompt: string) => {
             const url = await this.generateGPTImage(prompt);
             const field: Field = template.getFieldByID(Number(fieldNum));
@@ -629,33 +599,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             field.setTitle(col.title);
         };
 
-        const renderImageCalls = async (): Promise<Doc[]> => {
-            const rendered: Doc[] = [];
-            const calls = GPTIMGCalls;
-
-            if (calls.length) {
-                try {
-                    await Promise.all(
-                        calls.map(async ([fieldNum, col]) => {
-                            const sysPrompt =
-                                'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' +
-                                fieldContent +
-                                ' **** The user prompt is: ' +
-                                col.desc;
-
-                            const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
-
-                            generateAndLoadImage(fieldNum, col, prompt);
-                        })
-                    );
-                } catch (e) {
-                    console.log(e);
-                }
-            }
-
-            return rendered;
-        };
-
         const GPTTextCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.TEXT);
         const GPTIMGCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.VISUAL);
 
@@ -671,15 +614,50 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         let fieldContent: string = this.templateManager.getContentSummary(template);
 
-        const textCalls = await renderTextCalls();
-        const imageCalls = await renderImageCalls();
+        if (GPTTextCalls.length) {
+            try {
+                const prompt = fieldContent + GPTTextAssignment;
 
-        return template;
-    };
+                const res = await gptAPICall(prompt, GPTCallType.FILL);
 
-    renderTemplates = (templates: Template[]) => {
+                if (res) {
+                    const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
+                    //console.log('assignments', GPTAssignments, 'assignment string', GPTAssignmentString, 'field content', fieldContent, 'response', res, 'assignments', assignments);
+                    Object.entries(assignments).forEach(([title, info]) => {
+                        const field: Field = template.getFieldByID(Number(info.number));
+                        const col = this.getColByTitle(title);
 
-    }
+                        field.setContent(info.content ?? '', FieldContentType.STRING);
+                        field.setTitle(col.title);
+                    });
+                }
+            } catch (err) {
+                console.log(err);
+            }
+        }
+
+        if (GPTIMGCalls.length) {
+            try {
+                await Promise.all(
+                    GPTIMGCalls.map(async ([fieldNum, col]) => {
+                        const sysPrompt =
+                            'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' +
+                            fieldContent +
+                            ' **** The user prompt is: ' +
+                            col.desc;
+
+                        const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
+
+                        generateAndLoadImage(fieldNum, col, prompt);
+                    })
+                );
+            } catch (e) {
+                console.log(e);
+            }
+        };
+
+        return template;
+    };
 
     compileFieldDescriptions = (templates: Template[]): string => {
         let descriptions: string = '';
@@ -723,6 +701,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
             if (res && this._callCount === origCount) {
                 const assignments: { [templateTitle: string]: { [fieldID: string]: string } } = JSON.parse(res);
+                console.log('assignments', assignments)
                 const brokenDownAssignments: [Template, { [fieldID: number]: Col }][] = [];
 
                 Object.entries(assignments).forEach(([tempTitle, assignment]) => {
@@ -733,6 +712,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                             const col = this.getColByTitle(colTitle);
                             if (!this._userCreatedColumns.includes(col)){ // do the following for any fields not added by the user; will change in the future, for now only GPT content works with user-added fields
                                 const field = template.getFieldByID(Number(fieldID));
+                                //console.log(field);
                                 field.setContent(col.defaultContent ?? '', col.type === TemplateFieldType.VISUAL ? FieldContentType.IMAGE : FieldContentType.STRING);
                                 field.setTitle(col.title);
                             } else {
@@ -766,7 +746,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const renderedTemplates: Template[] = await Promise.all(renderedTemplatePromises);
 
         setTimeout(() => {
-            this.setGSuggestedTemplates(renderedTemplates.map(template => template.mainField.renderedDoc()));
+            this.setGSuggestedTemplates(templates.map(template => template.mainField.renderedDoc()));
             this._GPTLoading = false;
         });
     };
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
index f235d3218..c47db2007 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
@@ -60,13 +60,15 @@ export class DynamicField implements Field {
 
     setupSubfields = (): Field[] => {
         const fields: Field[] = [];
-        this.settings.subfields?.forEach(fieldSettings => {
+        this.settings.subfields?.forEach((fieldSettings, index) => {
             let field: Field;
             const dynamicType = fieldSettings.viewType;
 
-            if (dynamicType) { field = new DynamicField(fieldSettings, 0, this); }
+            const id = Number(String(this.id) + String(index));
 
-            field = new StaticField(fieldSettings, this, 0);
+            if (dynamicType) { field = new DynamicField(fieldSettings, id, this); }
+
+            field = new StaticField(fieldSettings, this, id);
             fields.push(field);
         });
         return fields;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
index 0f3631858..a0b25485a 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
@@ -53,6 +53,7 @@ export class StaticField {
     setContent = (newContent: string, type: FieldContentType) => { 
         this.content = newContent;
         this.contentType = type;
+        console.log('id: ', this.content)
     };
     getContent() { return this.content };
 
@@ -61,14 +62,16 @@ export class StaticField {
 
     setupSubfields = (): Field[] => {
         const fields: Field[] = [];
-        this.settings.subfields?.forEach(fieldSettings => {
+        this.settings.subfields?.forEach((fieldSettings, index) => {
             let field: Field;
             const type = fieldSettings.viewType;
 
+            const id = Number(String(this.id) + String(index));
+
             if (type === ViewType.FREEFORM || type === ViewType.CAROUSEL3D) { 
-                field = new DynamicField(fieldSettings, 0, this); 
+                field = new DynamicField(fieldSettings, id, this); 
             } else {
-                field = new StaticField(fieldSettings, this, 0);
+                field = new StaticField(fieldSettings, this, id);
             };
 
             fields.push(field);
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
index 708170359..69f5cfb81 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
@@ -24,7 +24,7 @@ export class Template {
     }
 
     setupMainField = (templateInfo: FieldSettings) => {
-        return new DynamicField(templateInfo, 0);
+        return new DynamicField(templateInfo, 1);
     }
 
     isValidTemplate = (cols: Col[]) => {
@@ -56,8 +56,6 @@ export class Template {
         const used: boolean[] = Array(fieldsCt).fill(false);
         const mt: number[] = Array(fieldsCt).fill(-1);
 
-        console.log(matches, fieldsCt);
-
         const augmentingPath = (v: number): boolean => {
             if (used[v]) return false;
             used[v] = true;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
index a23c3ba3d..166d27228 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
@@ -21,6 +21,7 @@ export class TemplateLayouts {
     }
 
     public static FourField001: FieldSettings = {
+        title: 'fourfield001',
         tl: [0, 0],
         br: [416, 700],
         viewType: ViewType.FREEFORM,
@@ -90,6 +91,7 @@ export class TemplateLayouts {
     };
 
     public static FourField002: FieldSettings = {
+        title: 'fourfield002',
         viewType: ViewType.FREEFORM,
         tl: [0,0],
         br: [425, 778],
@@ -260,6 +262,7 @@ export class TemplateLayouts {
     // };
 
     public static FourField004: FieldSettings = {
+        title: 'fourfield04',
         viewType: ViewType.FREEFORM,
         tl: [0,0],
         br: [414,583],
@@ -336,6 +339,7 @@ export class TemplateLayouts {
     };
 
     public static ThreeField001: FieldSettings = {
+        title: 'threefield001',
         viewType: ViewType.FREEFORM,
         tl: [0,0],
         br: [575, 770],
@@ -420,6 +424,7 @@ export class TemplateLayouts {
     };
 
     public static ThreeField002: FieldSettings = {
+        title: 'threefield002',
         viewType: ViewType.FREEFORM,
         tl: [0,0],
         br: [477, 662],
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
index 535bd423f..d47ae802c 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -30,7 +30,6 @@ export class TemplateManager {
     }
 
     getValidTemplates = (cols: Col[]): Template[] => {
-        console.log(this.templates.filter(template => template.isValidTemplate(cols)));
         return this.templates.filter(template => template.isValidTemplate(cols));
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 9b42bf8ab277979194e4ef73152b6b23c479786b Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Thu, 7 Nov 2024 03:36:50 -0500
Subject: gpt text gen working for previews

---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   | 107 ---------------------
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.scss  |   3 +-
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   |  40 +++-----
 .../DocCreatorMenu/FieldTypes/StaticField.tsx      |   2 -
 .../nodes/DataVizBox/DocCreatorMenu/Template.tsx   |  17 +++-
 .../DataVizBox/DocCreatorMenu/TemplateBackend.tsx  |   5 +-
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx  |  12 ---
 7 files changed, 36 insertions(+), 150 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 6621c610f..dececd1dc 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -511,7 +511,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     openDocCreatorMenu = (x: number, y: number) => {
         DocCreatorMenu.Instance.toggleDisplay(x, y);
         DocCreatorMenu.Instance.setDataViz(this);
-        DocCreatorMenu.Instance.setTemplateDocs(this.getPossibleTemplates());
     };
 
     specificContextMenu = (e: React.MouseEvent) => {
@@ -623,112 +622,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         }
     };
 
-    getPossibleTemplates = (): Doc[] => {
-        const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(this.Document).map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)));
-        const linkedCollections: Doc[] = linkedDocs.filter(doc => doc.type === 'config').map(doc => DocCast(doc.annotationOn));
-        const isColumnTitle = (title: string): boolean => {
-            const colTitles: string[] = Object.keys(this.records[0]);
-            for (let i = 0; i < colTitles.length; ++i) {
-                if (colTitles[i] === title) {
-                    return true;
-                }
-            }
-            return false;
-        };
-        const isValidTemplate = (collection: Doc) => {
-            const childDocs = DocListCast(collection[Doc.LayoutFieldKey(collection)]);
-            for (let i = 0; i < childDocs.length; ++i) {
-                if (isColumnTitle(String(childDocs[i].title))) return true;
-            }
-            return false;
-        };
-        return linkedCollections.filter(col => isValidTemplate(col));
-    };
-
-    ApplyTemplateTo = (templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) => {
-        if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) {
-            if (target.resolvedDataDoc) {
-                target[targetKey] = new PrefetchProxy(templateDoc);
-            } else {
-                titleTarget && (Doc.GetProto(target).title = titleTarget);
-                const setDoc = [AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(Doc.GetProto(target))) ? Doc.GetProto(target) : target;
-                setDoc[targetKey] = new PrefetchProxy(templateDoc);
-            }
-        }
-        return target;
-    };
-
-    applyLayout = (templateInfo: DataVizTemplateInfo, docs: Doc[]) => {
-        if (templateInfo.layout.type === LayoutType.STACKED) return;
-        const columns: number = templateInfo.columns;
-        const xGap: number = templateInfo.layout.xMargin;
-        const yGap: number = templateInfo.layout.yMargin;
-        // const repeat: number = templateInfo.layout.repeat;
-        const startX: number = templateInfo.referencePos.x;
-        const startY: number = templateInfo.referencePos.y;
-        const templWidth = Number(templateInfo.doc._width);
-        const templHeight = Number(templateInfo.doc._height);
-
-        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 += templWidth + xGap;
-                ++docsChanged;
-                ++i;
-            }
-
-            i = 0;
-            curX = startX;
-            curY += templHeight + yGap;
-        }
-    };
-
-    // @action addSavedLayout = (layout: DataVizTemplateLayout) => {
-    //     const saved = Cast(this.layoutDoc.dataViz_savedTemplates, listSpec('RefField'));
-
-    // }
-
-    @action
-    createDocsFromTemplate = (templateInfo: DataVizTemplateInfo, returnList?: boolean): Doc[] => {
-        if (!templateInfo.doc) {console.log('noinfo'); return []; }
-        const fields: string[] = Array.from(Object.keys(this.records[0]));
-        const selectedRows = NumListCast(this.layoutDoc.dataViz_selectedRows);
-        const docs: Doc[] = selectedRows.map(row => {
-            const values: string[] = [];
-            fields.forEach(col => values.push(this.records[row][col]));
-
-            
-
-            const proto = new Doc();
-            proto.author = ClientUtils.CurrentUserEmail();
-            values.forEach((val, i) => {
-                proto[fields[i]] = val as FieldType;
-            });
-
-            const target = Doc.MakeDelegate(proto);
-            const targetKey = StrCast(templateInfo.doc!.layout_fieldKey, 'layout');
-            const applied = this.ApplyTemplateTo(templateInfo.doc!, target, targetKey, templateInfo.doc!.title + `${row}`);
-            target.layout_fieldKey = targetKey;
-
-            //this.applyImagesTo(target, fields);
-            return applied;
-        });
-
-        if (returnList) return docs;
-
-        const mainCollection = this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
-        docs.forEach(doc => mainCollection.addDocument(doc));
-
-        this.applyLayout(templateInfo, docs);
-        return [];
-    };
-
     /**
      * creates a new dataviz document filter from this one
      *      it appears to the right of this document, with the
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
index b849c044d..98d630dae 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
@@ -45,9 +45,10 @@
         font-size: 12px;
         width: 18px;
         height: 18px;
-        border-radius: 2px;
         font-size: 12px;
         margin-left: auto;
+        margin-right: 5px;
+        margin-bottom: 3px;
     }
 
     &.options {
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index a08686a36..379a33a99 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -123,7 +123,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
     @action setSuggestedTemplates = (templates: Template[]) => {
         this._suggestedTemplates = templates;
-        templates.forEach(template => { this._suggestedTemplatePreviews.push({template: template, doc: template.mainField.renderedDoc()}) }); //prettier-ignore
+        this._suggestedTemplatePreviews = templates.map(template => {return {template: template, doc: template.mainField.renderedDoc()}}); //prettier-ignore
     };
 
     @computed get docsToRender() {
@@ -497,7 +497,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
      * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
      * @returns a doc containing the fully rendered template
      */
-    applyGPTContentToTemplate = async (template: Template, assignments: { [field: string]: Col }): Promise<Template> => {
+    applyGPTContentToTemplate = async (template: Template, assignments: { [field: string]: Col }): Promise<Template | undefined> => {
         const wordLimit = (size: TemplateFieldSize) => {
             switch (size) {
                 case TemplateFieldSize.TINY:
@@ -526,6 +526,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const GPTTextCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.TEXT);
         const GPTIMGCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.VISUAL);
 
+        if (!GPTTextCalls && !GPTIMGCalls) return;
+
         const stringifyGPTInfo = (calls: [string, Col][]): string => {
             let string: string = '*** COLUMN INFO:';
             calls.forEach(([fieldNum, col]) => {
@@ -536,13 +538,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const GPTTextAssignment = stringifyGPTInfo(GPTTextCalls);
 
-        let fieldContent: string = this.templateManager.getContentSummary(template);
+
+        let fieldContent: string = template.compiledContent;
 
         if (GPTTextCalls.length) {
             try {
                 const prompt = fieldContent + GPTTextAssignment;
 
-                const res = await gptAPICall(prompt, GPTCallType.FILL);
+                const res = await gptAPICall(`${++this._callCount}: ${prompt}`, GPTCallType.FILL);
 
                 if (res) {
                     const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
@@ -586,11 +589,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     compileFieldDescriptions = (templates: Template[]): string => {
         let descriptions: string = '';
         templates.forEach(template => {
-            console.log('title: ', template.mainField.getTitle());
             descriptions += `----------  NEW TEMPLATE TO INCLUDE: The title is: ${template.mainField.getTitle()}. Its fields are: `;
-            template.contentFields.forEach(field => {
-                descriptions += `{Field #${field.getID}: ${field.getDescription}} `;
-            });
+            descriptions += template.descriptionSummary;
         });
 
         return descriptions;
@@ -624,9 +624,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         try {
             const res = await gptAPICall(prompt, GPTCallType.TEMPLATE);
 
-            if (res && this._callCount === origCount) {
+            if (res) {
                 const assignments: { [templateTitle: string]: { [fieldID: string]: string } } = JSON.parse(res);
-                console.log('assignments', assignments)
                 const brokenDownAssignments: [Template, { [fieldID: number]: Col }][] = [];
 
                 Object.entries(assignments).forEach(([tempTitle, assignment]) => {
@@ -667,9 +666,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const assignments: [Template, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
 
-        const renderedTemplatePromises: Promise<Template>[] = assignments.map(([template, assignments]) => this.applyGPTContentToTemplate(template, assignments));
+        const renderedTemplatePromises: Promise<Template | undefined>[] = assignments.map(([template, assignments]) => this.applyGPTContentToTemplate(template, assignments));
 
-        //const renderedTemplates: Template[] = await Promise.all(renderedTemplatePromises);
+        const renderedTemplates: (Template | undefined)[] = await Promise.all(renderedTemplatePromises);
 
         setTimeout(() => {
             this.setSuggestedTemplates(templates);
@@ -1029,13 +1028,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         }
     };
 
-    addDocAsResult = (doc: Doc) => {
-        doc.x = this._pageX;
-        doc.y = this._pageY;
-        this.closeMenu();
-        //!!! will need to add to main collection when I refactor 
-    }
-
     @computed
     get previewInfo(){
         const docHeight: number = Number(this._fullyRenderedDocs[0]._height);
@@ -1078,8 +1070,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const collection: Doc = collectionFactory()(this._fullyRenderedDocs, {
             isDefaultTemplateDoc: true,
-            x: 40000,
-            y: 40000,
             _height: verticalSpan,
             _width: horizontalSpan,
             title: 'title',
@@ -1243,9 +1233,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     get dashboardContents() {
         const sizes: string[] = ['tiny', 'small', 'medium', 'large', 'huge'];
 
-        const fieldPanel = (field: Col) => {
+        const fieldPanel = (field: Col, id: number) => {
             return (
-                <div className="field-panel" key={field.title}>
+                <div className="field-panel" key={id}>
                     <div className="top-bar">
                         <span className="field-title">{`${field.title} Field`}</span>
                         <button className="docCreatorMenu-menu-button section-reveal-options no-margin" onPointerDown={e => this.setUpButtonClick(e, () => this.removeField(field))} style={{ position: 'absolute', right: '0px' }}>
@@ -1328,7 +1318,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                         <FontAwesomeIcon icon="arrow-left" />
                     </button>
                 </div>
-                <div className="panels-container">{this.fieldsInfos.map(field => fieldPanel(field))}</div>
+                <div className="panels-container">{this.fieldsInfos.map((field, i) => fieldPanel(field, i))}</div>
             </div>
         );
     }
@@ -1434,7 +1424,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                             <div className="docCreatorMenu-top-buttons-container">
                                 {topButton('lightbulb', 'templates', onPreviewSelected, 'left')}
                                 {topButton('magnifying-glass', 'options', onOptionsSelected, 'middle')}
-                                {topButton('floppy-disk', 'saved', onSavedSelected, 'right')}
+                                {topButton('bars', 'saved', onSavedSelected, 'right')}
                             </div>
                             <button className="docCreatorMenu-menu-button close-menu" onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}>
                                 <FontAwesomeIcon icon={'minus'} />
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
index 3e0c8abcf..033900fe9 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
@@ -119,7 +119,6 @@ export class StaticField {
         switch (this.contentType) {
             case FieldContentType.STRING:
                 const text = String(this.content);
-                console.log('made text')
                 doc = Docs.Create.TextDocument(text, {
                     title: this.title,
                     text_fontColor: oldDoc ? String(oldDoc.color) : opts.color,
@@ -131,7 +130,6 @@ export class StaticField {
                 FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc);
                 break;
             case FieldContentType.IMAGE:
-                console.log('made image')
                 const url = String(this.content);
                 doc = Docs.Create.ImageDocument(url, {
                     title: this.title,
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
index 4c6425f23..7d32d26d1 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
@@ -32,6 +32,22 @@ export class Template {
         return new DynamicField(templateInfo, 1);
     }
 
+    get descriptionSummary(): string {
+        let summary: string = '';
+        this.contentFields.forEach(field => {
+            summary += `--- Field #${field.getID} (title: ${field.getTitle()}): ${field.getDescription ?? ''} ---`;
+        });
+        return summary;
+    }
+
+    get compiledContent(): string {
+        let summary: string = '';
+        this.contentFields.forEach(field => {
+            summary += `--- Field #${field.getID} (title: ${field.getTitle()}): ${field.getContent() ?? ''} ---`;
+        });
+        return summary;
+    }
+
     renderUpdates = () => {
         this.allFields.forEach(field => {
             field.updateRenderedDoc(field.renderedDoc());
@@ -45,7 +61,6 @@ export class Template {
     }
 
     getMatches = (cols: Col[]): number[][] => {
-        console.log(this.mainField.getTitle(), this.allFields)
         const numFields = this.contentFields.length;
 
         if (cols.length !== numFields) return [];
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
index d434e98b1..9b8ec64c0 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
@@ -109,6 +109,7 @@ export class TemplateLayouts {
                 opts: {
                     borderWidth: '8',
                     borderColor: '#F8E71C',
+                    backgroundColor: '#242425',
                 },
             },
             {
@@ -143,9 +144,9 @@ export class TemplateLayouts {
                 viewType: ViewType.STATIC,
                 tl: [-0.83, 0.2],
                 br: [0.83, 0.95],
-                types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+                types: [TemplateFieldType.TEXT],
                 sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-                description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus, or share focus with field 1.',
+                description: 'A medium to large-sized field suitable for longer text that should contextualize field 1.',
                 opts: {
                     borderWidth: '8',
                     borderColor: '#F8E71C',
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
index d47ae802c..890bc6f73 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -17,18 +17,6 @@ export class TemplateManager {
         return initializedTemplates;
     }
 
-    /**
-     * Provides a text summary of content currently filled into a template, formatted for GPT analysis.
-     * @param template the template to be summarized
-     */
-    getContentSummary = (template: Template) => {
-        let summary: string = '';
-        template.contentFields.forEach(field => {
-            summary += `--- Field #${field.getID} (title: ${field.getTitle()}): ${field.getContent() ?? ''} ---`;
-        });
-        return summary;
-    }
-
     getValidTemplates = (cols: Col[]): Template[] => {
         return this.templates.filter(template => template.isValidTemplate(cols));
     }
-- 
cgit v1.2.3-70-g09d2


From 0a8f3739cf5c30852f18751a4c05d81e0dabe928 Mon Sep 17 00:00:00 2001
From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com>
Date: Tue, 4 Mar 2025 04:19:01 -0500
Subject: linting

---
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   | 156 ++++++++++-----------
 .../DocCreatorMenu/FieldTypes/DynamicField.tsx     |  21 ++-
 .../DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx |  61 ++++----
 .../DocCreatorMenu/FieldTypes/StaticField.tsx      |  13 +-
 .../nodes/DataVizBox/DocCreatorMenu/Template.tsx   |   2 -
 .../DataVizBox/DocCreatorMenu/TemplateBackend.tsx  |   2 +-
 .../DataVizBox/DocCreatorMenu/TemplateManager.tsx  |   1 -
 7 files changed, 116 insertions(+), 140 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index 7b28a06a3..7bc1b8064 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -1,24 +1,22 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Colors } from 'browndash-components';
-import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { IDisposer } from 'mobx-utils';
 import * as React from 'react';
 import ReactLoading from 'react-loading';
-import { ClientUtils, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../../ClientUtils';
+import { ClientUtils, returnEmptyFilter, returnFalse, setupMoveUpEvents } from '../../../../../ClientUtils';
 import { emptyFunction } from '../../../../../Utils';
-import { Doc, FieldType, NumListCast, StrListCast, returnEmptyDoclist } from '../../../../../fields/Doc';
+import { Doc, NumListCast, StrListCast, returnEmptyDoclist } from '../../../../../fields/Doc';
 import { Id } from '../../../../../fields/FieldSymbols';
-import { Cast, DocCast, ImageCast, StrCast } from '../../../../../fields/Types';
+import { ImageCast, StrCast } from '../../../../../fields/Types';
 import { ImageField } from '../../../../../fields/URLField';
 import { Networking } from '../../../../Network';
 import { GPTCallType, gptAPICall, gptImageCall } from '../../../../apis/gpt/GPT';
 import { Docs, DocumentOptions } from '../../../../documents/Documents';
 import { DragManager } from '../../../../util/DragManager';
-import { MakeTemplate } from '../../../../util/DropConverter';
 import { SnappingManager } from '../../../../util/SnappingManager';
 import { UndoManager, undoable } from '../../../../util/UndoManager';
-import { LightboxView } from '../../../LightboxView';
 import { ObservableReactComponent } from '../../../ObservableReactComponent';
 import { CollectionFreeFormView } from '../../../collections/collectionFreeForm/CollectionFreeFormView';
 import { DocumentView, DocumentViewInternal } from '../../DocumentView';
@@ -26,14 +24,13 @@ import { FieldViewProps } from '../../FieldView';
 import { OpenWhere } from '../../OpenWhere';
 import { DataVizBox } from '../DataVizBox';
 import './DocCreatorMenu.scss';
-import { DefaultStyleProvider, returnEmptyDocViewList } from '../../../StyleProvider';
+import { DefaultStyleProvider } from '../../../StyleProvider';
 import { Transform } from '../../../../util/Transform';
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { TemplateFieldSize, TemplateFieldType, TemplateLayouts } from './TemplateBackend';
 import { TemplateManager } from './TemplateManager';
 import { Template } from './Template';
 import { Field, FieldContentType } from './FieldTypes/Field';
-import { TabDocView } from '../../../collections/TabDocView';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
 
 export enum LayoutType {
     FREEFORM = 'Freeform',
@@ -43,6 +40,29 @@ export enum LayoutType {
     CARD = 'Card View',
 }
 
+export interface DataVizTemplateInfo {
+    doc: Doc;
+    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
+    columns: number;
+    referencePos: { x: number; y: number };
+}
+
+export interface DataVizTemplateLayout {
+    template: Doc;
+    docsNumList: number[];
+    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
+    columns: number;
+    rows: number;
+}
+
+export type Col = {
+    sizes: TemplateFieldSize[];
+    desc: string;
+    title: string;
+    type: TemplateFieldType;
+    defaultContent?: string;
+};
+
 @observer
 export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     static Instance: DocCreatorMenu;
@@ -89,8 +109,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     @observable _dragging: boolean = false;
     @observable _draggingIndicator: boolean = false;
     @observable _dataViz?: DataVizBox;
-    @observable _interactionLock: any;
-    @observable _snapPt: any;
+    @observable _interactionLock: boolean | undefined;
+    @observable _snapPt: {x: number, y: number} = {x: 0, y: 0};
     @observable _resizeHdlId: string = '';
     @observable _resizing: boolean = false;
     @observable _offset: { x: number; y: number } = { x: 0, y: 0 };
@@ -195,7 +215,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         return bounds;
     }
 
-    setUpButtonClick = (e: any, func: Function) => {
+    setUpButtonClick = (e: any, func: () => void) => {
         setupMoveUpEvents(
             this,
             e,
@@ -249,11 +269,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         document.removeEventListener('pointerup', this.onPointerUp);
     }
 
-    @action
-    updateSelectedCols = (cols: string[]) => {
-        this._selectedCols;
-    };
-
     @action
     toggleDisplay = (x: number, y: number) => {
         if (this._shouldDisplay) {
@@ -302,7 +317,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         this._interactionLock = true;
         const scaleAspect = {x: scale.x, y: scale.y};
         this.resizeView(refPt, scaleAspect, transl); // prettier-ignore
-        await new Promise<any>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
+        await new Promise<boolean | undefined>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
         }); // prettier-ignore
         return true;
     };
@@ -318,7 +333,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
     getResizeVals = (thisPt: { x: number; y: number }, dragHdl: string) => {
         const [w, h] = [this._initDimensions.width, this._initDimensions.height];
-        const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y];
+        const [moveX, moveY] = [thisPt.x - this._snapPt!.x, thisPt.y - this._snapPt!.y];
         let vals: { scale: { x: number; y: number }; refPt: [number, number]; transl: { x: number; y: number } };
         switch (dragHdl) {
             case 'topLeft':    vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h },  refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: moveY } }; break;
@@ -335,7 +350,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     resizeView = (refPt: number[], scale: { x: number; y: number }, translation: { x: number; y: number }) => {
-        const refCent = [refPt[0], refPt[1]]; // fixed reference point for resize (ie, a point that doesn't move)
         if (this._initDimensions.x === undefined) this._initDimensions.x = this._pageX;
         if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY;
         const { height, width, x, y } = this._initDimensions;
@@ -475,8 +489,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const GPTTextCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.TEXT && this._userCreatedFields.includes(col));
         const GPTIMGCalls = Object.entries(assignments).filter(([str, col]) => col.type === TemplateFieldType.VISUAL && this._userCreatedFields.includes(col));
 
-        let fieldContent: string = template.compiledContent;
-
         if (GPTTextCalls.length) {
             const promises = GPTTextCalls.map(([str, col]) => {
                 return this.renderGPTTextCall(template, col, Number(str));
@@ -527,7 +539,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         ++this._callCount;
         const origCount = this._callCount;
 
-        let prompt: string = `(${origCount}) ${inputText}`;
+        const prompt: string = `(${origCount}) ${inputText}`;
 
         this._GPTLoading = true;
 
@@ -539,7 +551,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 const brokenDownAssignments: [Template, { [fieldID: number]: Col }][] = [];
 
                 Object.entries(assignments).forEach(([tempTitle, assignment]) => {
-                    const template = templates.filter(template => template.mainField.getTitle() === tempTitle)[0];
+                    const template = templates.filter(t => t.mainField.getTitle() === tempTitle)[0];
                     if (!template) return;
                     const toObj = Object.entries(assignment).reduce(
                         (a, [fieldID, colTitle]) => {
@@ -575,9 +587,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const assignments: [Template, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
 
-        const renderedTemplatePromises: Promise<Template | undefined>[] = assignments.map(([template, assignments]) => this.applyGPTContentToTemplate(template, assignments));
+        const renderedTemplatePromises: Promise<Template | undefined>[] = assignments.map(([template, asns]) => this.applyGPTContentToTemplate(template, asns));
 
-        const renderedTemplates: (Template | undefined)[] = await Promise.all(renderedTemplatePromises);
+        await Promise.all(renderedTemplatePromises);
 
         setTimeout(() => {
             this.setSuggestedTemplates(templates);
@@ -585,16 +597,16 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         });
     };
 
-    renderGPTImageCall = async (template: Template, col: Col, fieldNum: number): Promise<boolean> => {
-        const generateAndLoadImage = async (fieldNum: string, col: Col, prompt: string) => {
+    renderGPTImageCall = async (template: Template, col: Col, fieldNumber: number): Promise<boolean> => {
+        const generateAndLoadImage = async (fieldNum: string, column: Col, prompt: string) => {
             const url = await this.generateGPTImage(prompt);
             const field: Field = template.getFieldByID(Number(fieldNum));
 
             field.setContent(url ?? '', FieldContentType.IMAGE);
-            field.setTitle(col.title);
+            field.setTitle(column.title);
         };
 
-        let fieldContent: string = template.compiledContent;
+        const fieldContent: string = template.compiledContent;
 
         try {
             const sysPrompt =
@@ -605,7 +617,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
             const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
 
-            await generateAndLoadImage(String(fieldNum), col, prompt);
+            await generateAndLoadImage(String(fieldNumber), col, prompt);
         } catch (e) {
             console.log(e);
         }
@@ -632,7 +644,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const textAssignment = `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`;
 
-        let fieldContent: string = template.compiledContent;
+        const fieldContent: string = template.compiledContent;
 
         try {
             const prompt = fieldContent + textAssignment;
@@ -643,10 +655,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
                 Object.entries(assignments).forEach(([title, info]) => {
                     const field: Field = template.getFieldByID(Number(info.number));
-                    const col = this.getColByTitle(title);
+                    const column = this.getColByTitle(title);
 
                     field.setContent(info.content ?? '', FieldContentType.STRING);
-                    field.setTitle(col.title);
+                    field.setTitle(column.title);
                 });
             }
         } catch (err) {
@@ -667,7 +679,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const selectedRows = NumListCast(dv.layoutDoc.dataViz_selectedRows);
     
         const rowContents: { [title: string]: string }[] = selectedRows.map(row => {
-            let values: { [title: string]: string } = {};
+            const values: { [title: string]: string } = {};
             fields.forEach(col => {
                 values[col] = dv.records[row][col];
             });
@@ -756,7 +768,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                     focus={emptyFunction}
                     styleProvider={DefaultStyleProvider}
                     addDocTab={DocumentViewInternal.addDocTabFunc}
-                    // eslint-disable-next-line no-use-before-define
                     pinToPres={() => undefined}
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
@@ -786,7 +797,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     }
 
     get templatesPreviewContents() {
-        const renderedTemplates: Doc[] = [];
 
         const GPTOptions = <div></div>;
 
@@ -813,6 +823,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                         .map(({doc, template}) => (
                                             <div
                                                 className="docCreatorMenu-preview-window"
+                                                key='0'
                                                 style={{
                                                     border: this._selectedTemplate === template ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
                                                     boxShadow: this._selectedTemplate === template ? `0 0 15px rgba(68, 118, 247, .8)` : '',
@@ -844,7 +855,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                                     focus={emptyFunction}
                                                     styleProvider={DefaultStyleProvider}
                                                     addDocTab={this._props.addDocTab}
-                                                    // eslint-disable-next-line no-use-before-define
                                                     pinToPres={() => undefined}
                                                     childFilters={returnEmptyFilter}
                                                     childFiltersByRanges={returnEmptyFilter}
@@ -882,6 +892,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                     .map(({template, doc}) => (
                                         <div
                                             className="docCreatorMenu-preview-window"
+                                            key='0'
                                             style={{
                                                 border: this._selectedTemplate === template ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
                                                 boxShadow: this._selectedTemplate === template ? `0 0 15px rgba(68, 118, 247, .8)` : '',
@@ -913,7 +924,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                                 focus={emptyFunction}
                                                 styleProvider={DefaultStyleProvider}
                                                 addDocTab={this._props.addDocTab}
-                                                // eslint-disable-next-line no-use-before-define
                                                 pinToPres={() => undefined}
                                                 childFilters={returnEmptyFilter}
                                                 childFiltersByRanges={returnEmptyFilter}
@@ -953,11 +963,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     get layoutConfigOptions() {
-        const optionInput = (icon: string, func: Function, def?: number, key?: string, noMargin?: boolean) => {
+        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 any} />
+                        <FontAwesomeIcon icon={icon as IconProp} />
                     </div>
                     <input defaultValue={def} onInput={e => func(e.currentTarget.value)} className="docCreatorMenu-input config layout-config" />
                 </div>
@@ -1070,16 +1080,16 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         this._renderedDocCollection = collection;
     }
 
-    layoutPreviewContents = (id?: number) => {
+    layoutPreviewContents = () => {
 
         return this._docsRendering ? (
-            <div className="docCreatorMenu-layout-preview-window-wrapper loading" id={String(id) ?? undefined}>
+            <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" id={String(id) ?? undefined}>
+            <div className="docCreatorMenu-layout-preview-window-wrapper">
                 <DocumentView
                     Document={this._renderedDocCollection}
                     isContentActive={emptyFunction}
@@ -1094,7 +1104,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                     focus={emptyFunction}
                     styleProvider={DefaultStyleProvider}
                     addDocTab={this._props.addDocTab}
-                    // eslint-disable-next-line no-use-before-define
                     pinToPres={() => undefined}
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
@@ -1108,7 +1117,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     get optionsMenuContents() {
-        const layoutOption = (option: LayoutType, optStyle?: {}, specialFunc?: Function) => {
+        const layoutOption = (option: LayoutType, optStyle?: object, specialFunc?: () => void) => {
             return (
                 <div
                     className="docCreatorMenu-dropdown-option"
@@ -1131,7 +1140,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             return (
                 <div className="docCreatorMenu-option-container">
                     <div className={`docCreatorMenu-option-title config ${specClass}`} style={{ width: width * 0.4, height: height }}>
-                        <FontAwesomeIcon icon={icon as any} />
+                        <FontAwesomeIcon icon={icon as IconProp} />
                     </div>
                     {manual ? (
                         <input className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }} />
@@ -1162,13 +1171,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                     </div>
                 </div>
                 {this._layout.type ? this.layoutConfigOptions : null}
-                {this.layoutPreviewContents(this._menuDimensions.width * 0.75)}
+                {this.layoutPreviewContents()}
                 {selectionBox(
                     60,
                     20,
                     'repeat',
                     undefined,
-                    repeatOptions.map(num => <option onPointerDown={e => (this._layout.repeat = num)}>{`${num}x`}</option>)
+                    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">
@@ -1333,19 +1342,19 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const width: number = ref?.width ?? 0;
 
         return [
-            <div className='docCreatorMenu-resizer top' onPointerDown={this.onResizePointerDown} style={{width: width, left: 0, top: -7}}/>, 
-            <div className='docCreatorMenu-resizer left' onPointerDown={this.onResizePointerDown} style={{height: height, left: -7, top: 0}}/>,
-            <div className='docCreatorMenu-resizer right' onPointerDown={this.onResizePointerDown} style={{height: height, left: width - 3, top: 0}}/>, 
-            <div className='docCreatorMenu-resizer bottom' onPointerDown={this.onResizePointerDown} style={{width: width, left: 0, top: height - 3}}/>,
-            <div className='docCreatorMenu-resizer topLeft' onPointerDown={this.onResizePointerDown} style={{left: -10, top: -10, cursor: 'nwse-resize'}}/>,
-            <div className='docCreatorMenu-resizer topRight' onPointerDown={this.onResizePointerDown} style={{left: width - 5, top: -10, cursor: 'nesw-resize'}}/>,
-            <div className='docCreatorMenu-resizer bottomLeft' onPointerDown={this.onResizePointerDown} style={{left: -10, top: height - 5, cursor: 'nesw-resize'}}/>,
-            <div className='docCreatorMenu-resizer bottomRight' onPointerDown={this.onResizePointerDown} style={{left: width - 5, top: height - 5, cursor: 'nwse-resize'}}/>,
+            <div className='docCreatorMenu-resizer top' key='0' onPointerDown={this.onResizePointerDown} style={{width: width, left: 0, top: -7}}/>, 
+            <div className='docCreatorMenu-resizer left' key='1' onPointerDown={this.onResizePointerDown} style={{height: height, left: -7, top: 0}}/>,
+            <div className='docCreatorMenu-resizer right' key='2' onPointerDown={this.onResizePointerDown} style={{height: height, left: width - 3, top: 0}}/>, 
+            <div className='docCreatorMenu-resizer bottom' key='3' onPointerDown={this.onResizePointerDown} style={{width: width, left: 0, top: height - 3}}/>,
+            <div className='docCreatorMenu-resizer topLeft' key='4' onPointerDown={this.onResizePointerDown} style={{left: -10, top: -10, cursor: 'nwse-resize'}}/>,
+            <div className='docCreatorMenu-resizer topRight' key='5' onPointerDown={this.onResizePointerDown} style={{left: width - 5, top: -10, cursor: 'nesw-resize'}}/>,
+            <div className='docCreatorMenu-resizer bottomLeft' key='6' onPointerDown={this.onResizePointerDown} style={{left: -10, top: height - 5, cursor: 'nesw-resize'}}/>,
+            <div className='docCreatorMenu-resizer bottomRight' key='7' onPointerDown={this.onResizePointerDown} style={{left: width - 5, top: height - 5, cursor: 'nwse-resize'}}/>,
         ]; //prettier-ignore
     }
 
     render() {
-        const topButton = (icon: string, opt: string, func: Function, tag: string) => {
+        const topButton = (icon: string, opt: string, func: () => void, tag: string) => {
             return (
                 <div className={`top-button-container ${tag} ${opt === this._menuContent ? 'selected' : ''}`}>
                     <div
@@ -1357,7 +1366,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                 })
                             )
                         }>
-                        <FontAwesomeIcon icon={icon as any} />
+                        <FontAwesomeIcon icon={icon as IconProp} />
                     </div>
                 </div>
             );
@@ -1396,11 +1405,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                                 setupMoveUpEvents(
                                     this,
                                     e,
-                                    e => {
+                                    event => {
                                         this._dragging = true;
                                         this._startPos = { x: 0, y: 0 };
-                                        this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
-                                        this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
+                                        this._startPos.x = event.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
+                                        this._startPos.y = event.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
                                         document.addEventListener('pointermove', this.onDrag);
                                         return true;
                                     },
@@ -1426,26 +1435,3 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         );
     }
 }
-
-export interface DataVizTemplateInfo {
-    doc: Doc;
-    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
-    columns: number;
-    referencePos: { x: number; y: number };
-}
-
-export interface DataVizTemplateLayout {
-    template: Doc;
-    docsNumList: number[];
-    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
-    columns: number;
-    rows: number;
-}
-
-export type Col = {
-    sizes: TemplateFieldSize[];
-    desc: string;
-    title: string;
-    type: TemplateFieldType;
-    defaultContent?: string;
-};
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
index 68cf027b0..c5254c17d 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
@@ -1,8 +1,6 @@
 import { Doc } from "../../../../../../fields/Doc";
 import { Docs } from "../../../../../documents/Documents";
-import { Col } from "../DocCreatorMenu";
-import { TemplateLayouts } from "../TemplateBackend";
-import { Field, FieldContentType, FieldDimensions, FieldSettings, ViewType } from "./Field";
+import { Field, FieldDimensions, FieldSettings, ViewType } from "./Field";
 import { FieldUtils } from "./FieldUtils";
 import { StaticField } from "./StaticField";
 
@@ -30,7 +28,7 @@ export class DynamicField implements Field {
         this.subfields = this.setupSubfields();
     }
 
-    setContent = (content: string, type?: FieldContentType) => { return };
+    setContent = () => { return };
     getContent = () => { return '' };
 
     setTitle = (title: string) => { this.title = title };
@@ -54,7 +52,7 @@ export class DynamicField implements Field {
         return this.settings.description ?? '';
     }
 
-    matches = (cols: Col[]): Array<number> => {
+    matches = (): Array<number> => {
         return [];
     }
 
@@ -97,19 +95,20 @@ export class DynamicField implements Field {
     };
 
     renderedDoc = (): Doc => {
+        let doc: Doc;
         switch (this.settings.viewType) {
             case ViewType.CAROUSEL3D:
-                const carouselDoc = Docs.Create.Carousel3DDocument(this.subfields.map(field => field.renderedDoc()), {
+                doc = Docs.Create.Carousel3DDocument(this.subfields.map(field => field.renderedDoc()), {
                     title: this.title,
                 });
-                FieldUtils.applyBasicOpts(carouselDoc, this.dimensions, this.settings);
-                return carouselDoc;
+                FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings);
+                return doc;
             case ViewType.FREEFORM:
-                const freeformDoc = Docs.Create.FreeformDocument(this.subfields.map(field => field.renderedDoc()), {
+                doc = Docs.Create.FreeformDocument(this.subfields.map(field => field.renderedDoc()), {
                     title: this.title,
                 });
-                FieldUtils.applyBasicOpts(freeformDoc, this.dimensions, this.settings);
-                return freeformDoc;
+                FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings);
+                return doc;
             default:
                 return new Doc();
         }
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
index ebd8f0f6c..ea9b566b3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
@@ -2,36 +2,6 @@ import { Doc } from "../../../../../../fields/Doc";
 import { Col } from "../DocCreatorMenu";
 import { TemplateFieldSize, TemplateFieldType } from "../TemplateBackend";
 
-export interface Field {
-    getContent: () => string;
-    setContent: (content: string, type?: FieldContentType) => void;
-    getDimensions: FieldDimensions;
-    getSubfields: Field[];
-    getAllSubfields: Field[];
-    getID: number;
-    getViewType: ViewType;
-    getDescription: string;
-    getTitle: () => string;
-    setTitle: (title: string) => void;
-    setupSubfields: () => Field[];
-    applyAttributes: (field: Field) => void;
-    renderedDoc: () => Doc;
-    matches: (cols: Col[]) => number[];
-    updateRenderedDoc: (oldDoc?: Doc) => Doc;
-}
-
-export type FieldSettings = {
-    tl: [number, number];
-    br: [number, number];
-    opts: FieldOpts;
-    viewType: ViewType;
-    title?: string;
-    subfields?: FieldSettings[];
-    types?: TemplateFieldType[];
-    sizes?: TemplateFieldSize[];
-    description?: string;
-};
-
 export enum FieldContentType {
     STRING = 'string',
     IMAGE = 'image',
@@ -60,8 +30,37 @@ export interface FieldOpts {
     contentYCentering?: 'top' | 'center' | 'bottom';
     opacity?: number;
     rotation?: number;
-    //animation?: boolean;
     fontBold?: boolean;
     fontTransform?: 'uppercase' | 'lowercase';
     fieldViewType?: 'freeform' | 'stacked';
+}
+
+export type FieldSettings = {
+    tl: [number, number];
+    br: [number, number];
+    opts: FieldOpts;
+    viewType: ViewType;
+    title?: string;
+    subfields?: FieldSettings[];
+    types?: TemplateFieldType[];
+    sizes?: TemplateFieldSize[];
+    description?: string;
+};
+
+export interface Field {
+    getContent: () => string;
+    setContent: (content: string, type?: FieldContentType) => void;
+    getDimensions: FieldDimensions;
+    getSubfields: Field[];
+    getAllSubfields: Field[];
+    getID: number;
+    getViewType: ViewType;
+    getDescription: string;
+    getTitle: () => string;
+    setTitle: (title: string) => void;
+    setupSubfields: () => Field[];
+    applyAttributes: (field: Field) => void;
+    renderedDoc: () => Doc;
+    matches: (cols: Col[]) => number[];
+    updateRenderedDoc: (oldDoc?: Doc) => Doc;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
index e55c127e7..47b43f051 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
@@ -1,9 +1,6 @@
-import { TbHospital } from "react-icons/tb";
 import { Doc } from "../../../../../../fields/Doc";
-import { FieldType } from "../../../../../../fields/ObjectField";
-import { Docs, DocumentOptions } from "../../../../../documents/Documents";
+import { Docs } from "../../../../../documents/Documents";
 import { Col } from "../DocCreatorMenu";
-import { Template } from "../Template";
 import { DynamicField } from "./DynamicField";
 import { FieldUtils } from "./FieldUtils";
 import { Field, FieldContentType, FieldDimensions, FieldSettings, ViewType } from "./Field";
@@ -124,20 +121,18 @@ export class StaticField {
 
         switch (this.contentType) {
             case FieldContentType.STRING:
-                const text = String(this.content);
-                doc = Docs.Create.TextDocument(text, {
+                doc = Docs.Create.TextDocument(String(this.content), {
                     title: this.title,
                     text_fontColor: oldDoc ? String(oldDoc.color) : opts.color,
                     contentBold: oldDoc ? Boolean(oldDoc.fontBold) : opts.fontBold,
                     textTransform: oldDoc ? String(oldDoc.fontTransform) : opts.fontTransform,
                     color: oldDoc ? String(oldDoc.color) : opts.color,
-                    _text_fontSize: `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, text, true)}`
+                    _text_fontSize: `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, String(this.content), true)}`
                 });
                 FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc);
                 break;
             case FieldContentType.IMAGE:
-                const url = String(this.content);
-                doc = Docs.Create.ImageDocument(url, {
+                doc = Docs.Create.ImageDocument(String(this.content), {
                     title: this.title,
                     _layout_fitWidth: false,
                 });
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
index 39215eb06..0a5097d4a 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
@@ -1,6 +1,4 @@
-
 import { Doc, FieldType } from "../../../../../fields/Doc";
-import { Docs } from "../../../../documents/Documents";
 import { Col } from "./DocCreatorMenu";
 import { DynamicField } from "./FieldTypes/DynamicField";
 import { Field, FieldSettings, ViewType } from "./FieldTypes/Field";
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
index 99edce34e..d3282eda3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
@@ -1,4 +1,4 @@
-import { FieldOpts, FieldSettings, ViewType } from "./FieldTypes/Field";
+import { FieldSettings, ViewType } from "./FieldTypes/Field";
 import { } from "./FieldTypes/StaticField";
 
 export enum TemplateFieldType {
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
index 890bc6f73..50ae4d72a 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
@@ -1,7 +1,6 @@
 import { Col } from "./DocCreatorMenu";
 import { FieldSettings } from "./FieldTypes/Field";
 import { Template } from "./Template";
-import { TemplateLayouts } from "./TemplateBackend";
 
 export class TemplateManager {
 
-- 
cgit v1.2.3-70-g09d2

