diff options
author | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-12-07 19:46:07 -0500 |
---|---|---|
committer | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-12-07 19:46:07 -0500 |
commit | fe744903609e669c5f3048743ceba9268b8dfe0d (patch) | |
tree | 194120ee62b0a8faab6a2545ae667fdf7ef2030a | |
parent | 047bd02ea4f2a7f565ddfb5da9d1c0685d18e08e (diff) |
field superclass
6 files changed, 121 insertions, 202 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx index 079d222d3..d8a71a610 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx @@ -400,7 +400,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { testTemplate = async () => { const obj = new DocumentOptions(); - console.log(Object.entries(obj)[1][0]); //console.log(this.templateManager.templates) @@ -545,7 +544,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { compileFieldDescriptions = (templates: Template[]): string => { let descriptions: string = ''; templates.forEach(template => { - descriptions += `---------- NEW TEMPLATE TO INCLUDE: The title is: ${template.mainField.getTitle()}. Its fields are: `; + descriptions += `---------- NEW TEMPLATE TO INCLUDE: The title is: ${template.title}. Its fields are: `; descriptions += template.descriptionSummary; }); @@ -585,7 +584,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(template => template.title === tempTitle)[0]; if (!template) return; const toObj = Object.entries(assignment).reduce( (a, [fieldID, colTitle]) => { @@ -707,7 +706,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { createDocsFromTemplate = async (template: Template) => { const dv = this._dataViz; - console.log('dataviz: ', dv); + if (!dv) return; this._docsRendering = true; @@ -781,7 +780,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { @action setExpandedView = (template: Template | undefined) => { if (template) { this._currEditingTemplate = template; - this._expandedPreview = template.mainField.renderedDoc(); //Docs.Create.FreeformDocument([doc], { _height: NumListCast(doc._height)[0], _width: NumListCast(doc._width)[0], title: ''}); + this._expandedPreview = template.doc; //Docs.Create.FreeformDocument([doc], { _height: NumListCast(doc._height)[0], _width: NumListCast(doc._width)[0], title: ''}); } else { this._currEditingTemplate = undefined; this._expandedPreview = undefined; @@ -839,6 +838,31 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { const GPTOptions = <div></div>; + const previewDoc = (doc: Doc, template: Template) => + <DocumentView + Document={doc} + isContentActive={emptyFunction} // !!! should be return false + addDocument={returnFalse} + moveDocument={returnFalse} + removeDocument={returnFalse} + PanelWidth={() => this._selectedTemplate === template ? 104 : 111} + PanelHeight={() => this._selectedTemplate === template ? 104 : 111} + ScreenToLocalTransform={() => new Transform(-this._pageX - 5,-this._pageY - 35, 1)} + renderDepth={1} + whenChildContentsActiveChanged={emptyFunction} + focus={emptyFunction} + styleProvider={DefaultStyleProvider} + addDocTab={this._props.addDocTab} + // eslint-disable-next-line no-use-before-define + pinToPres={() => undefined} + childFilters={returnEmptyFilter} + childFiltersByRanges={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} + fitContentsToBox={returnFalse} + fitWidth={returnFalse} + hideDecorations={true} + /> + //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} /> return ( @@ -881,29 +905,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.addUserTemplate(template))}> <FontAwesomeIcon icon="plus" color="white" /> </button> - <DocumentView - Document={doc} - isContentActive={emptyFunction} // !!! should be return false - addDocument={returnFalse} - moveDocument={returnFalse} - removeDocument={returnFalse} - PanelWidth={() => this._selectedTemplate === template ? 104 : 111} - PanelHeight={() => this._selectedTemplate === template ? 104 : 111} - ScreenToLocalTransform={() => new Transform(-this._pageX - 5,-this._pageY - 35, 1)} - renderDepth={1} - whenChildContentsActiveChanged={emptyFunction} - focus={emptyFunction} - styleProvider={DefaultStyleProvider} - addDocTab={this._props.addDocTab} - // eslint-disable-next-line no-use-before-define - pinToPres={() => undefined} - childFilters={returnEmptyFilter} - childFiltersByRanges={returnEmptyFilter} - searchFilterDocs={returnEmptyDoclist} - fitContentsToBox={returnFalse} - fitWidth={returnFalse} - hideDecorations={true} - /> + {previewDoc(doc, template)} </div> )) )} @@ -950,29 +952,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.removeUserTemplate(template))}> <FontAwesomeIcon icon="minus" color="white" /> </button> - <DocumentView - Document={doc} - isContentActive={emptyFunction} // !!! should be return false - addDocument={returnFalse} - moveDocument={returnFalse} - removeDocument={returnFalse} - PanelWidth={() => this._selectedTemplate === template ? 104 : 111} - PanelHeight={() => this._selectedTemplate === template ? 104 : 111} - ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)} - renderDepth={1} - whenChildContentsActiveChanged={emptyFunction} - focus={emptyFunction} - styleProvider={DefaultStyleProvider} - addDocTab={this._props.addDocTab} - // eslint-disable-next-line no-use-before-define - pinToPres={() => undefined} - childFilters={returnEmptyFilter} - childFiltersByRanges={returnEmptyFilter} - searchFilterDocs={returnEmptyDoclist} - fitContentsToBox={returnFalse} - fitWidth={returnFalse} - hideDecorations={true} - /> + {previewDoc(doc, template)} </div> ))} </div> diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx index 428f4a01c..681e1d48c 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx @@ -9,25 +9,14 @@ import { StaticField } from "./StaticField"; import { IDisposer } from "mobx-utils"; export class DynamicField extends Field { - private disposers: { [name: string]: IDisposer } = {}; - - private subfields: Field[] = []; - - private id: number; - private settings: FieldSettings; - private title: string = ''; - private parent: Field; - private dimensions: FieldDimensions; + protected dimensions: FieldDimensions; - private renderedDocument: Doc; + protected renderedDocument: Doc; constructor(settings: FieldSettings, id: number, parent?: Field) { super(settings, id); makeAutoObservable(this); - 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]}}; @@ -35,7 +24,7 @@ export class DynamicField extends Field { this.parent = parent; this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions); } - this.subfields = this.setupSubfields(); + this.renderedDocument = new Doc(); //!!! // this.disposers.fieldList = reaction( // () => DocListCast(this.doc[Doc.LayoutFieldKey(this.doc)]), @@ -48,78 +37,10 @@ export class DynamicField extends Field { setContent = (content: string, type?: FieldContentType) => { return }; getContent = () => { return '' }; - setTitle = (title: string) => { this.title = title }; - getTitle = () => { return this.title }; - - // addField = () => { - // const newField: Field = new DynamicField(); - // //this.subfields.pu - // } - - get getSubfields() { return this.subfields }; - get getAllSubfields() { - let fields: Field[] = []; - this.subfields?.forEach(field => { - fields.push(field); - fields = fields.concat(field.getAllSubfields) - }); - return fields; - }; - - get getDimensions() { return this.dimensions }; - get getID() { return this.id }; - get getViewType() { return this.settings.viewType }; - - get getDescription(): string { - return this.settings.description ?? ''; - } - - // dispose = () => { - // Object.values(this.disposers).forEach(disposer => disposer?.()); - // } - - // handleFieldUpdate = (newDocsList: Doc[]) => { - // const currRenderedDocs: Set<Doc> = new Set(); - // this.subfields.forEach(field => currRenderedDocs.add(field.renderedDoc())); - // newDocsList.forEach(doc => { - // if (!currRenderedDocs.has(doc)) { - // this.addField(doc); - // } - // }); - // currRenderedDocs.forEach(); - // } - matches = (cols: Col[]): Array<number> => { return []; } - updateRenderedDoc = () => { - return new Doc(); - } - - setupSubfields = (): Field[] => { - const fields: Field[] = []; - this.settings.subfields?.forEach((fieldSettings, index) => { - let field: Field; - const type = fieldSettings.viewType; - - const id = Number(String(this.id) + String(index)); - - if (type == ViewType.CAROUSEL3D || type === ViewType.FREEFORM) { - field = new DynamicField(fieldSettings, id, this); - } else { - field = new StaticField(fieldSettings, this, id); - } - fields.push(field); - }); - return fields; - } - - applyAttributes = (field: Field) => { - field.setTitle(this.title); - field.updateRenderedDoc(this.renderedDoc()); - } - getChildDimensions = (coords: { tl: [number, number]; br: [number, number] }): FieldDimensions => { const l = (coords.tl[0] * this.dimensions.height) / 2; const t = coords.tl[1] * this.dimensions.width / 2; //prettier-ignore @@ -131,16 +52,16 @@ export class DynamicField extends Field { return { width, height, coord }; }; - renderedDoc = (): Doc => { + updateRenderedDoc = (): Doc => { switch (this.settings.viewType) { case ViewType.CAROUSEL3D: - const carouselDoc = Docs.Create.Carousel3DDocument(this.subfields.map(field => field.renderedDoc()), { + const carouselDoc = Docs.Create.Carousel3DDocument(this.subfields.map(field => field.renderedDoc), { title: this.title, }); FieldUtils.applyBasicOpts(carouselDoc, this.dimensions, this.settings); return carouselDoc; case ViewType.FREEFORM: - const freeformDoc = Docs.Create.FreeformDocument(this.subfields.map(field => field.renderedDoc()), { + const freeformDoc = Docs.Create.FreeformDocument(this.subfields.map(field => field.renderedDoc), { title: this.title, }); FieldUtils.applyBasicOpts(freeformDoc, this.dimensions, this.settings); diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx index 14f7cb109..4d0aa10c8 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx @@ -1,12 +1,17 @@ -import { Doc } from "../../../../../../fields/Doc"; +import { makeAutoObservable, reaction } from "mobx"; +import { Doc, DocListCast } from "../../../../../../fields/Doc"; import { Col } from "../DocCreatorMenu"; import { TemplateFieldSize, TemplateFieldType } from "../TemplateBackend"; import { DynamicField } from "./DynamicField"; import { FieldUtils } from "./FieldUtils"; import { StaticField } from "./StaticField"; +import { IDisposer } from "mobx-utils"; +import { DocumentType } from "../../../../../documents/DocumentTypes"; export abstract class Field { - protected subfields: Field[] = []; + protected disposers: { [name: string]: IDisposer } = {}; + + protected subfields: Field[]; protected abstract renderedDocument: Doc; @@ -17,9 +22,19 @@ export abstract class Field { protected abstract dimensions: FieldDimensions; constructor(settings: FieldSettings, id: number) { + makeAutoObservable(this); + this.id = id; this.settings = settings; this.title = settings.title ?? ''; + this.subfields = this.setupSubfields(); + + this.disposers.fieldList = reaction( + () => DocListCast(this.renderedDocument[Doc.LayoutFieldKey(this.renderedDocument)]), + docs => { + this.handleFieldUpdate(docs); + } + ); } get getSubfields(): Field[] { return this.subfields ?? []; }; @@ -36,6 +51,7 @@ export abstract class Field { 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) => { this.title = title; @@ -46,15 +62,41 @@ export abstract class Field { abstract setContent(content: string, type?: FieldContentType): void; abstract getContent(): string; - addField = () => {}; - removeField = () => {}; + addFieldFromDoc = (doc: Doc) => { + const settings: FieldSettings = { + tl: [Number(doc._x), Number(doc._y)], + br: [Number(doc._x) + Number(doc._width), Number(doc._y) + Number(doc._height)], + viewType: doc.type === DocumentType.COL ? ViewType.FREEFORM : ViewType.STATIC, + opts: {}, + }; + + Object.getOwnPropertyNames(FieldOpts.prototype).forEach(([key, value]) => { + settings.opts[key as keyof FieldOpts] = StringCast(doc[key]); + }); + + const newField = this.setupField(settings, this.subfields.length) + this.subfields.push(newField); + }; + + addField = (type?: FieldContentType) => { + + } + + removeField = (field: Field) => { + this.subfields.splice(this.subfields.indexOf(field), 1); + field.dispose(); + }; + + private setupField = (settings: FieldSettings, index: number): Field => { + const id = Number(`${this.id}${index}`); + return settings.viewType === ViewType.FREEFORM || settings.viewType === ViewType.CAROUSEL3D + ? new DynamicField(settings, id, this) + : new StaticField(settings, this, id); + } setupSubfields = (): Field[] => { return this.settings.subfields?.map((fieldSettings, index) => { - const id = Number(`${this.id}${index}`); - return fieldSettings.viewType === ViewType.FREEFORM || fieldSettings.viewType === ViewType.CAROUSEL3D - ? new DynamicField(fieldSettings, id, this) - : new StaticField(fieldSettings, this, id); + return this.setupField(fieldSettings, index); }) || []; } @@ -67,6 +109,26 @@ export abstract class Field { abstract matches(cols: Col[]): Array<number>; + dispose = () => { + Object.values(this.disposers).forEach(disposer => disposer?.()); + } + + handleFieldUpdate = (newDocsList: Doc[]) => { + const currRenderedDocs: Set<Doc> = new Set(); + this.subfields.forEach(field => currRenderedDocs.add(field.renderedDoc)); + newDocsList.forEach(doc => { + if (!currRenderedDocs.has(doc)) { + this.addFieldFromDoc(doc); + } + }); + currRenderedDocs.forEach(doc => { + if (!newDocsList.includes(doc)){ + const fields = this.subfields.filter(field => field.renderedDoc === doc); + fields.forEach(field => this.removeField(field)); + } + }); + } + } export type FieldSettings = { @@ -99,7 +161,7 @@ export type FieldDimensions = { coord: {x: number, y: number}; } -export interface FieldOpts { +export class FieldOpts { backgroundColor?: string; text_fontColor?: string; _layout_borderRounding?: number; @@ -114,3 +176,7 @@ export interface FieldOpts { textTransform?: 'uppercase' | 'lowercase'; fieldViewType?: 'freeform' | 'stacked'; } +function StringCast(arg0: unknown): undefined { + throw new Error("Function not implemented."); +} + diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx index 88115c529..94ff7b8e8 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx @@ -14,7 +14,6 @@ import { makeAutoObservable, reaction } from "mobx"; import { IDisposer } from "mobx-utils"; export class StaticField extends Field { - private disposers: { [name: string]: IDisposer } = {}; private content: string; private contentType: FieldContentType | undefined; @@ -31,33 +30,10 @@ export class StaticField extends Field { this.parent = parent; this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions); this.content = ''; - this.subfields = this.setupSubfields(); this.renderedDocument = this.setupRenderedDoc(); this.storedAttributes = new DocumentOptions(); - - this.disposers.fieldList = reaction( - () => DocListCast(this.renderedDocument[Doc.LayoutFieldKey(this.renderedDocument)]), - docs => { - this.handleFieldUpdate(docs); - } - ); - }; - - get getSubfields(): Field[] { return this.subfields ?? []; }; - - get getAllSubfields(): Field[] { - let fields: Field[] = []; - this.subfields?.forEach(field => { - fields.push(field); - fields = fields.concat(field.getAllSubfields); - }); - return fields; }; - get getDescription(): string { - return this.settings.description ?? ''; - } - setContent = (newContent: string, type?: FieldContentType) => { this.content = newContent; if (type) this.contentType = type; @@ -70,35 +46,6 @@ export class StaticField extends Field { field.setContent('', this.contentType); } - setupSubfields = (): Field[] => { - return this.settings.subfields?.map((fieldSettings, index) => { - const id = Number(`${this.id}${index}`); - return fieldSettings.viewType === ViewType.FREEFORM || fieldSettings.viewType === ViewType.CAROUSEL3D - ? new DynamicField(fieldSettings, id, this) - : new StaticField(fieldSettings, this, id); - }) || []; - } - - dispose = () => { - Object.values(this.disposers).forEach(disposer => disposer?.()); - } - - handleFieldUpdate = (newDocsList: Doc[]) => { - const currRenderedDocs: Set<Doc> = new Set(); - this.subfields.forEach(field => currRenderedDocs.add(field.renderedDoc)); - newDocsList.forEach(doc => { - if (!currRenderedDocs.has(doc)) { - this.addField(doc); - } - }); - currRenderedDocs.forEach(doc => { - if (!newDocsList.includes(doc)){ - const fields = this.subfields.filter(field => field.renderedDoc === doc); - fields.forEach(field => this.removeField(field)); - } - }); - } - matches = (cols: Col[]): number[] => { const colMatchesField = (col: Col) => { const isMatch: boolean = ( diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx index add588046..e079af4de 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx @@ -12,7 +12,7 @@ import { IDisposer } from "mobx-utils"; export class Template { - private mainField: DynamicField; + mainField: DynamicField; private settings: FieldSettings; constructor(templateInfo: FieldSettings) { @@ -24,7 +24,12 @@ 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 doc(){ return this.mainField.renderedDoc(); }; + get doc(){ return this.mainField.renderedDoc; }; + get title() { return this.mainField.getTitle() }; + + cleanup = () => { + //dispose each subfields disposers, etc. + } cloneBase = () => { const clone: Template = new Template(this.settings); @@ -76,7 +81,7 @@ export class Template { renderUpdates = () => { this.allFields.forEach(field => { - field.updateRenderedDoc(field.renderedDoc()); + field.updateRenderedDoc(field.renderedDoc); }); }; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx index 310b19890..413c3082e 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx @@ -30,6 +30,6 @@ export class TemplateManager { removeTemplate = (template: Template) => { this.templates.splice(this.templates.indexOf(template), 1); - template.dispose(); + template.cleanup(); } }
\ No newline at end of file |