From fe1536918dbbca08c9900497bb466fd7aa36ffdf Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sat, 22 Feb 2025 15:02:26 -0500 Subject: Splitting staticfield into different content types (as subclasses) --- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 8 +- .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx | 10 +- .../DocCreatorMenu/EditableTemplateDoc.tsx | 22 --- .../DocCreatorMenu/FieldTypes/DynamicField.tsx | 3 +- .../DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx | 36 ++-- .../DocCreatorMenu/FieldTypes/FieldUtils.tsx | 14 +- .../DocCreatorMenu/FieldTypes/StaticContentField | 98 ++++++++++ .../DocCreatorMenu/FieldTypes/StaticField.tsx | 214 --------------------- .../nodes/DataVizBox/DocCreatorMenu/Template.tsx | 3 +- .../DataVizBox/DocCreatorMenu/TemplateBackend.tsx | 1 - 10 files changed, 145 insertions(+), 264 deletions(-) delete mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/EditableTemplateDoc.tsx create mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticContentField delete mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx (limited to 'src') diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 117311b8c..dececd1dc 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -411,10 +411,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { }, { fireImmediately: true } ); - // this._disposers.contentSummary = reaction( - // () => this.records, - // () => this.updateGPTSummary() - // ); + this._disposers.contentSummary = reaction( + () => this.records, + () => this.updateGPTSummary() + ); } fetchData = () => { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx index e8b80b7b5..b576aee82 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx @@ -32,7 +32,7 @@ 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 { Field, ViewType } from './FieldTypes/Field'; import { TabDocView } from '../../../collections/TabDocView'; export enum LayoutType { @@ -585,7 +585,7 @@ export class DocCreatorMenu extends ObservableReactComponent { const col = this.getColByTitle(colTitle); if (!this._userCreatedFields.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.setContent(col.defaultContent ?? '', col.type === TemplateFieldType.VISUAL ? ViewType.IMG : ViewType.TEXT); field.setTitle(col.title); } else { a[Number(fieldID)] = this.getColByTitle(colTitle); @@ -618,6 +618,8 @@ export class DocCreatorMenu extends ObservableReactComponent { const renderedTemplates: (Template | undefined)[] = await Promise.all(renderedTemplatePromises); + templates.forEach(template => template.mainField.updateRenderedDoc()) + setTimeout(() => { this.setSuggestedTemplates(templates); this._GPTLoading = false; @@ -630,7 +632,7 @@ export class DocCreatorMenu extends ObservableReactComponent { console.log('url: ', url) const field: Field = template.getFieldByID(Number(fieldNum)); - field.setContent(url ?? '', FieldContentType.IMAGE); + field.setContent(url ?? '', ViewType.IMG); field.setTitle(col.title); }; @@ -687,7 +689,7 @@ export class DocCreatorMenu extends ObservableReactComponent { const field: Field = template.getFieldByID(Number(info.number)); const col = this.getColByTitle(title); - field.setContent(info.content ?? '', FieldContentType.STRING); + field.setContent(info.content ?? '', ViewType.TEXT); field.setTitle(col.title); }); } diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/EditableTemplateDoc.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/EditableTemplateDoc.tsx deleted file mode 100644 index 5ec27f338..000000000 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/EditableTemplateDoc.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Doc } from "../../../../../fields/Doc"; -import { SubCollectionViewProps } from "../../../collections/CollectionSubView"; -import { CollectionFreeFormView } from "../../../collections/collectionFreeForm"; -import { TemplateManager } from "./TemplateManager"; -import { TemplateLayouts } from "./TemplateBackend"; -import { Template } from "./Template"; - -class EditableTemplateDoc extends CollectionFreeFormView { - - template: Template; - - constructor(props: SubCollectionViewProps, template: Template){ - super(props); - this.template = template; - } - - addDocumenta = (newBox: Doc | Doc[]): boolean => { - this.addDocument(newBox); - - return true; - } -} \ No newline at end of file diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx index c244dd57c..2d8328ed6 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx @@ -51,8 +51,7 @@ export class DynamicField extends Field { }; updateRenderedDoc = (): Doc => { - - //console.log('dynamic field updated'); + console.log('dynamic field updated'); let doc: Doc; const renderedSubfields: Doc[] = this.subfields.map(field => field.renderedDoc); switch (this.settings.viewType) { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx index 2aa9f9032..d164053c3 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx @@ -49,7 +49,6 @@ export abstract class Field { get renderedDoc(){ return this.renderedDocument }; get getDimensions() { return this.dimensions }; get getID() { return this.id }; - get getViewType() { return this.settings.viewType }; get getDescription(): string { return this.settings.description ?? '' }; setTitle = (title: string) => { @@ -58,7 +57,7 @@ export abstract class Field { }; getTitle = () => { return this.title }; - abstract setContent(content: string, type?: FieldContentType): void; + abstract setContent(content: string, type?: ViewType): void; abstract getContent(): string; setupFieldChangeReaction = () => { @@ -116,7 +115,7 @@ export abstract class Field { this.subfields.push(newField); }; - addField = (type?: FieldContentType) => { + addField = (type?: ViewType) => { } @@ -142,8 +141,6 @@ export abstract class Field { abstract updateRenderedDoc(oldDoc?: Doc): void; - abstract matches(cols: Col[]): Array; - dispose = () => { Object.values(this.disposers).forEach(disposer => disposer?.()); } @@ -165,6 +162,26 @@ export abstract class Field { }); } + matches = (cols: Col[]): number[] => { + const colMatchesField = (col: Col) => { + const isMatch: boolean = ( + this.settings.sizes?.some(size => col.sizes?.includes(size)) + && this.settings.types?.includes(col.type)) + ?? false; + return isMatch; + } + + const matches: Array = []; + + cols.forEach((col, v) => { + if (colMatchesField(col)) { + matches.push(v); + } + }); + + return matches; + }; + } export type FieldSettings = { @@ -179,16 +196,13 @@ export type FieldSettings = { description?: string; }; -export enum FieldContentType { - STRING = 'string', - IMAGE = 'image', -} - export enum ViewType { CAROUSEL3D = 'carousel3d', FREEFORM = 'freeform', STATIC = 'static', - DEC = 'decoration' + DEC = 'decoration', + IMG = 'image', + TEXT = 'text', } export type FieldDimensions = { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx index 27ea8e1f5..6a800b8d1 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx @@ -4,7 +4,7 @@ import { Col } from "../DocCreatorMenu"; import { TemplateFieldSize, TemplateFieldType, TemplateLayouts } from "../TemplateBackend"; import { DynamicField } from "./DynamicField"; import { Field, FieldDimensions, FieldSettings, ViewType } from "./Field"; -import { StaticField } from "./StaticField"; +import { TextTemplateField, ImageTemplateField } from "./StaticContentField"; export class FieldUtils { public static getLocalDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentDimensions: FieldDimensions): FieldDimensions => { @@ -23,9 +23,15 @@ export class FieldUtils { public static setupField = (settings: FieldSettings, index: number, parent: Field): Field => { //console.log('settings', settings); const id = Number(`${parent.getID}${index}`); - return settings.viewType === ViewType.FREEFORM || settings.viewType === ViewType.CAROUSEL3D - ? new DynamicField(settings, id, parent) - : new StaticField(settings, parent, id); + switch (settings.viewType) { + case ViewType.FREEFORM: case ViewType.CAROUSEL3D: + return new DynamicField(settings, id, parent); + case ViewType.IMG: + return new ImageTemplateField(settings, id, parent); + case ViewType.TEXT: + return new TextTemplateField(settings, id, parent); + } + return new TextTemplateField(settings, id, parent); } public static textProperties: string[] = [ diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticContentField b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticContentField new file mode 100644 index 000000000..da2671f9c --- /dev/null +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticContentField @@ -0,0 +1,98 @@ +import { Doc, DocListCast } from "../../../../../../fields/Doc"; +import { Docs, DocumentOptions } from "../../../../../documents/Documents"; +import { FieldUtils } from "./FieldUtils"; +import { Field, FieldDimensions, FieldSettings, ViewType } from "./Field"; +import { RichTextField } from "../../../../../../fields/RichTextField"; +import { DocData } from "../../../../../../fields/DocSymbols"; +import { ImageField } from "../../../../../../fields/URLField"; + +export abstract class StaticContentField extends Field { + + protected content: string; + protected renderedDocument: Doc; + protected subfields: Field[]; + + protected parent: Field; + protected dimensions: FieldDimensions; + + constructor(settings: FieldSettings, parent: Field, id: number) { + super(settings, id, FieldUtils.setupField, parent); + this.parent = parent; + this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions); + this.content = ''; + this.subfields = this.setupSubfields(this); + this.renderedDocument = this.updateRenderedDoc(); + }; + + abstract setContent(content: string): void; + getContent() { return this.content ?? 'unset'}; + + abstract updateRenderedDoc(): Doc; +} + +export class ImageTemplateField extends StaticContentField { + + setContent = (url: string) => { + const imgField = new ImageField(url); + this.renderedDocument[DocData]['data'] = imgField; + this.content = url; + }; + + updateRenderedDoc = (): Doc => { + const url = String(this.content); + let doc: Doc = Docs.Create.ImageDocument(url, { + title: this.title, + _layout_fitWidth: false, + }); + FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings); + + this.renderedDocument = doc; + + return doc; + }; +} + +export class TextTemplateField extends StaticContentField { + + setContent = (text: string) => { + const rtf = { + doc: { + type: 'doc', + content: [ + { + type: 'paragraph', + content: [ + { + type: 'text', + text, + }, + ], + }, + ], + }, + selection: { type: 'text', anchor: 1, head: 1 }, + storedMarks: [], + }; + this.content = text; + const field = new RichTextField(JSON.stringify(rtf), text); + this.renderedDocument[DocData]['text'] = field; + }; + + updateRenderedDoc = (): Doc => { + const opts = this.settings.opts; + const text = String(this.content); + let doc: Doc = Docs.Create.TextDocument(text, { + title: this.title, + text_fontColor: opts.text_fontColor, + contentBold: opts.contentBold, + textTransform: opts.textTransform, + color: opts.text_fontColor, + _text_fontSize: `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, text, true)}` + }); + FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings); + + this.renderedDocument = doc; + + return 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 deleted file mode 100644 index 2090d94b9..000000000 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import { Doc, DocListCast } from "../../../../../../fields/Doc"; -import { Docs, DocumentOptions } from "../../../../../documents/Documents"; -import { Col } from "../DocCreatorMenu"; -import { FieldUtils } from "./FieldUtils"; -import { Field, FieldContentType, FieldDimensions, FieldSettings, ViewType } from "./Field"; -import { RichTextField } from "../../../../../../fields/RichTextField"; - -export class StaticField extends Field { - - private content: string; - private contentType: FieldContentType | undefined; - protected renderedDocument: Doc; - protected subfields: Field[]; - - private storedAttributes: Record; - - protected parent: Field; - protected dimensions: FieldDimensions; - - constructor(settings: FieldSettings, parent: Field, id: number) { - super(settings, id, FieldUtils.setupField, parent); - this.parent = parent; - this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions); - this.content = ''; - this.subfields = this.setupSubfields(this); - this.renderedDocument = this.updateRenderedDoc(); - this.storedAttributes = new DocumentOptions(); - }; - - setContent = (newContent: string, type?: FieldContentType) => { - console.log('set to: ', newContent) - const rtf = { - doc: { - type: 'doc', - content: [ - { - type: 'paragraph', - content: [ - { - type: 'text', - newContent, - }, - ], - }, - ], - }, - selection: { type: 'text', anchor: 1, head: 1 }, - storedMarks: [], - }; - const field = new RichTextField(JSON.stringify(rtf), newContent); - this.content = newContent; - // this.renderedDocument['data'] = field; - if (type) this.contentType = type; - - this.updateRenderedDoc(this.renderedDocument /*, true*/); - }; - getContent() { return this.content ?? 'Unset'}; - - applyAttributes = (field: Field) => { //!!! can be updated later for more robust clonign; this is all ythat's needed now - super.applyAttributes(field); - field.setContent('', this.contentType); - } - - matches = (cols: Col[]): number[] => { - const colMatchesField = (col: Col) => { - const isMatch: boolean = ( - this.settings.sizes?.some(size => col.sizes?.includes(size)) - && this.settings.types?.includes(col.type)) - ?? false; - return isMatch; - } - - const matches: Array = []; - - cols.forEach((col, v) => { - if (colMatchesField(col)) { - matches.push(v); - } - }); - - return matches; - }; - - updateRenderedDoc = (oldDoc?: Doc): Doc => { - const opts = this.settings.opts; - - if (!this.contentType) { this.contentType = FieldContentType.STRING }; - - let doc: Doc; - - switch (this.contentType) { - case FieldContentType.STRING: - const text = String(this.content); - console.log('creating text doc with text: ', text) - doc = Docs.Create.TextDocument(text, { - title: this.title, - text_fontColor: oldDoc ? String(oldDoc.color) : opts.text_fontColor, - contentBold: oldDoc ? Boolean(oldDoc.fontBold) : opts.contentBold, - textTransform: oldDoc ? String(oldDoc.fontTransform) : opts.textTransform, - color: oldDoc ? String(oldDoc.color) : opts.text_fontColor, - _text_fontSize: `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, text, true)}` - }); - FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc); - break; - case FieldContentType.IMAGE: - const url = String(this.content); - doc = Docs.Create.ImageDocument(url, { - title: this.title, - _layout_fitWidth: false, - }); - FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc); - break; - } - - //doc[this.title] = this.content; broken for some reason - - this.renderedDocument = doc; - - return doc; - }; - - // updateRenderedDoc = (currDoc?: Doc, forceRerender?: boolean) => { - - // if (!this.contentType) { this.contentType = FieldContentType.STRING }; - - // let doc: Doc; - - // // if (this.shouldRerender() || forceRerender) { - // // } else { - // // this.updateStoredAttributes(this.renderedDocument); - // // } - - // this.updateStoredAttributes(this.renderedDocument); - - // let list: string[] = Object.entries(this.storedAttributes).map(([key, value]) => `${key}: ${value}`); - // console.log(list); - - // switch (this.contentType) { - // case FieldContentType.STRING: - // const text = String(this.content); - // this.storedAttributes._text_fontSize = `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, this.content, true)}` - // doc = Docs.Create.TextDocument(text, this.storedAttributes); - // break; - // case FieldContentType.IMAGE: - // const url = String(this.content); - // doc = Docs.Create.ImageDocument(url, this.storedAttributes); - // break; - // } - // doc._layout_hideScroll = true; - - - // console.log(StrCast(doc.backgroundColor), StrCast(doc._rotation)); - - // this.renderedDocument = doc; - - // //this.renderedDocument = doc; - // }; - - // private updateStoredAttributes = (currDoc?: Doc) => { - // const opts = this.settings.opts; - // console.log("num atts", Object.entries(this.storedAttributes).length); - // Object.entries(this.storedAttributes).forEach(([key, value]) => { - // key = String(key); - // if (currDoc && currDoc[key] !== undefined) { - // this.storedAttributes[key] = currDoc[key]; - // } else if (opts[key as keyof typeof opts] !== undefined) { - // this.storedAttributes[key] = opts[key as keyof typeof opts]; - // } - // }); - // } - - // private shouldRerender = (): boolean => { - // return FieldUtils.textProperties.some(property => - // this.renderedDocument[property] !== this.storedAttributes[property] - // ); - // }; - - private setupRenderedDoc = (): Doc => { - const docOptions: Record = new DocumentOptions(); - - docOptions.isDefaultTemplateDoc = true; - docOptions.x = this.dimensions.coord.x; - docOptions.y = this.dimensions.coord.y; - docOptions._height = this.dimensions.height; - docOptions._width = this.dimensions.width; - docOptions._nativeWidth = this.dimensions.width; - docOptions._nativeHeight = this.dimensions.height; - - Object.entries(this.settings.opts).forEach(([key, value]) => { - docOptions[key] = value; - }); - - let doc: Doc; - switch (this.contentType) { - case FieldContentType.STRING: - doc = Docs.Create.TextDocument(this.content, docOptions); - break; - case FieldContentType.IMAGE: - doc = Docs.Create.ImageDocument(this.content, docOptions); - break; - default: - doc = Docs.Create.TextDocument(this.content, docOptions); - break; - } - - doc._layout_hideScroll = true; - //doc._layout_borderRounding = !opts._layout_borderRounding ? '0px' : ScriptField.MakeFunction(`${opts._layout_borderRounding} * this.width + 'px'`); - - this.renderedDocument = doc; - - return doc; - } - -} \ No newline at end of file diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx index 16e70a47b..9d132d637 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx @@ -6,7 +6,6 @@ import { Col } from "./DocCreatorMenu"; import { DynamicField } from "./FieldTypes/DynamicField"; import { Field, FieldSettings, ViewType } from "./FieldTypes/Field"; import { } from "./FieldTypes/FieldUtils"; -import { } from "./FieldTypes/StaticField"; import { observer } from "mobx-react"; import { IDisposer } from "mobx-utils"; import { Width } from "../../../../../fields/DocSymbols"; @@ -25,7 +24,7 @@ export class Template { get childFields(): Field[] { return this.mainField.getSubfields }; get allFields(): Field[] { return this.mainField.getAllSubfields }; - get contentFields(): Field[] { return this.allFields.filter(field => field.getViewType === ViewType.STATIC) }; + get contentFields(): Field[] { return this.allFields.filter(field => field !instanceof DynamicField) }; get doc(){ return this.mainField.renderedDoc; }; get title() { return this.mainField.getTitle() }; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx index bea5c2d5d..583b2f472 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx @@ -1,5 +1,4 @@ import { FieldOpts, FieldSettings, ViewType } from "./FieldTypes/Field"; -import { } from "./FieldTypes/StaticField"; export enum TemplateFieldType { TEXT = 'text', -- cgit v1.2.3-70-g09d2