aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/views/Main.tsx3
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx306
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx117
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx66
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx79
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx147
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts (renamed from src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx)107
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.ts (renamed from src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx)306
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DecorationField.ts11
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts164
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/StaticContentField.ts72
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts159
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateFieldUtils.ts71
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.ts (renamed from src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx)25
-rw-r--r--src/client/views/smartdraw/DrawingFillHandler.tsx4
-rw-r--r--src/fields/Doc.ts2
17 files changed, 882 insertions, 759 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 317bb7feb..45d02e822 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -290,6 +290,7 @@ export class DocumentOptions {
_layout_showSidebar?: BOOLt = new BoolInfo('whether an annotationsidebar should be displayed for text docuemnts');
_layout_showCaption?: string; // which field to display in the caption area. leave empty to have no caption
_layout_showTags?: BOOLt = new BoolInfo('whether to show the list of document tags at the bottom of a DocView');
+ _layout_hideScroll?: BOOLt = new BoolInfo('whether to hide scroll bars on the document');
_chromeHidden?: BOOLt = new BoolInfo('whether the editing chrome for a document is hidden');
hideClickBehaviors?: BOOLt = new BoolInfo('whether to hide click behaviors in context menu');
@@ -742,6 +743,7 @@ export namespace Docs {
}
// users placeholderDoc as proto if it exists
+ console.log('placeholder: ', placeholderDocIn, ' data: ', dataProps['data'])
const dataDoc = Doc.assign(placeholderDoc ? Doc.GetProto(placeholderDoc) : Doc.MakeDelegate(proto, protoId), dataProps, undefined, true);
if (placeholderDoc) {
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 22725a2b9..b335432c9 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -65,6 +65,8 @@ import { PresBox, PresElementBox } from './nodes/trails';
import { FaceRecognitionHandler } from './search/FaceRecognitionHandler';
import { SearchBox } from './search/SearchBox';
import { StickerPalette } from './smartdraw/StickerPalette';
+import { TemplateField } from './nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField';
+import { TemplateFieldUtils } from './nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateFieldUtils';
dotenv.config();
@@ -100,6 +102,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
new PingManager();
new KeyManager();
new FaceRecognitionHandler();
+ TemplateField.initField = TemplateFieldUtils.initField; // set the init function for fields
// initialize plugins and classes that require plugins
CollectionDockingView.Init(TabDocView);
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index 64416c26d..97faf01c2 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -1,5 +1,6 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Colors } from '@dash/components';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { IDisposer } from 'mobx-utils';
@@ -11,26 +12,25 @@ import { Doc, NumListCast, StrListCast, returnEmptyDoclist } from '../../../../.
import { Id } from '../../../../../fields/FieldSymbols';
import { ImageCast, StrCast } from '../../../../../fields/Types';
import { ImageField } from '../../../../../fields/URLField';
+import { Upload } from '../../../../../server/SharedMediaTypes';
import { Networking } from '../../../../Network';
import { GPTCallType, gptAPICall, gptImageCall } from '../../../../apis/gpt/GPT';
import { Docs, DocumentOptions } from '../../../../documents/Documents';
import { DragManager } from '../../../../util/DragManager';
import { SnappingManager } from '../../../../util/SnappingManager';
+import { Transform } from '../../../../util/Transform';
import { UndoManager, undoable } from '../../../../util/UndoManager';
import { ObservableReactComponent } from '../../../ObservableReactComponent';
+import { DefaultStyleProvider } from '../../../StyleProvider';
import { CollectionFreeFormView } from '../../../collections/collectionFreeForm/CollectionFreeFormView';
import { DocumentView, DocumentViewInternal } from '../../DocumentView';
import { OpenWhere } from '../../OpenWhere';
import { DataVizBox } from '../DataVizBox';
import './DocCreatorMenu.scss';
-import { DefaultStyleProvider } from '../../../StyleProvider';
-import { Transform } from '../../../../util/Transform';
+import { TemplateField, ViewType } from './TemplateFieldTypes/TemplateField';
+import { Template } from './Template';
import { TemplateFieldSize, TemplateFieldType, TemplateLayouts } from './TemplateBackend';
import { TemplateManager } from './TemplateManager';
-import { Template } from './Template';
-import { Field, FieldContentType } from './FieldTypes/Field';
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { Upload } from '../../../../../server/SharedMediaTypes';
export enum LayoutType {
FREEFORM = 'Freeform',
@@ -72,18 +72,19 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
// eslint-disable-next-line no-use-before-define
static Instance: DocCreatorMenu;
+ private DEBUG_MODE: boolean = false;
+
private _disposers: { [name: string]: IDisposer } = {};
private _ref: HTMLDivElement | null = null;
private templateManager: TemplateManager;
- @observable _fullyRenderedDocs: Doc[] = [];
- @observable _renderedDocCollectionPreview: Doc | undefined = undefined;
- @observable _renderedDocCollection: Doc | undefined = undefined;
- @observable _docsRendering: boolean = false;
+ @observable _fullyRenderedDocs: Doc[] = []; // collection of templates filled in with content
+ @observable _renderedDocCollection: Doc | undefined = undefined; // fullyRenderedDocs in a parent collection
+ @observable _docsRendering: boolean = false; // dictates loading symbol
- @observable _userTemplates: { template: Template; doc: Doc }[] = []; //!!! used to keep track of all templates, should be refactored to work with actual templates and not docs
+ @observable _userTemplates: Template[] = [];
@observable _selectedTemplate: Template | undefined = undefined;
@observable _currEditingTemplate: Template | undefined = undefined;
@@ -91,7 +92,6 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
@observable _selectedCols: { title: string; type: string; desc: string }[] | undefined = [];
@observable _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.FREEFORM, yMargin: 10, xMargin: 10, columns: 3, repeat: 0 };
- @observable _layoutPreviewScale: number = 1;
@observable _savedLayouts: DataVizTemplateLayout[] = [];
@observable _expandedPreview: Doc | undefined = undefined;
@@ -100,6 +100,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
@observable _GPTOpt: boolean = false;
@observable _callCount: number = 0;
@observable _GPTLoading: boolean = false;
+ @observable _DOCCC: Doc | undefined;
@observable _pageX: number = 0;
@observable _pageY: number = 0;
@@ -135,31 +136,26 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
this._dataViz = dataViz;
this._selectedTemplate = undefined;
this._renderedDocCollection = undefined;
- this._renderedDocCollectionPreview = undefined;
this._fullyRenderedDocs = [];
- this._suggestedTemplatePreviews = [];
this._suggestedTemplates = [];
this._userCreatedFields = [];
};
@action addUserTemplate = (template: Template) => {
- this._userTemplates.push({ template: template.cloneBase(), doc: template.getRenderedDoc() });
+ this._userTemplates.push(template);
};
@action removeUserTemplate = (template: Template) => {
- this._userTemplates = this._userTemplates.filter(info => info.template !== template);
- };
- @action updateTemplatePreview = (template: Template) => {
- template.renderUpdates();
- const preview = { template: template, doc: template.getRenderedDoc() };
- this._suggestedTemplatePreviews = this._suggestedTemplatePreviews.map(t => { return t.template === preview.template ? preview : t }); //prettier-ignore
- this._userTemplates = this._userTemplates.map(t => { return t.template === preview.template ? preview : t }); //prettier-ignore
+ this._userTemplates.splice(this._userTemplates.indexOf(template), 1);
};
@action setSuggestedTemplates = (templates: Template[]) => {
- this._suggestedTemplates = templates;
- this._suggestedTemplatePreviews = templates.map(template => {return {template: template, doc: template.getRenderedDoc()}}); //prettier-ignore
+ this._suggestedTemplates = templates; //prettier-ignore
};
@computed get docsToRender() {
- return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : [];
+ if (this.DEBUG_MODE) {
+ return [1, 2, 3, 4];
+ } else {
+ return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : [];
+ }
}
@computed get rowsCount() {
@@ -374,15 +370,20 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
return undefined;
}
+ @action updateRenderedPreviewCollection = async (template: Template) => {
+ this._fullyRenderedDocs = ((await this.createDocsFromTemplate(template)) ?? []).filter(doc => doc).map(doc => doc!);
+ console.log(this._fullyRenderedDocs);
+ this.updateRenderedDocCollection();
+ };
+
@action updateSelectedTemplate = async (template: Template) => {
if (this._selectedTemplate === template) {
this._selectedTemplate = undefined;
return;
} else {
this._selectedTemplate = template;
- template.renderUpdates();
- this._fullyRenderedDocs = (await this.createDocsFromTemplate(template)) ?? [];
- this.updateRenderedDocCollection();
+ //template.renderUpdates();
+ this.updateRenderedPreviewCollection(template);
}
};
@@ -403,6 +404,33 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
Doc.UnBrushDoc(doc);
};
+ testTemplate = async () => {
+ this._suggestedTemplates = this.templateManager.templates; //prettier-ignore
+
+ //console.log(this.templateManager.templates)
+
+ // const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
+
+ // this.templateManager.templates.forEach(template => {
+ // const doc = template.mainField.renderedDoc();
+ // mainCollection.addDocument(doc);
+ // })
+
+ // this.forceUpdate();
+
+ // try {
+ // const res = await gptImageCall('Image of panda eating a cookie');
+
+ // if (res) {
+ // const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
+
+ // console.log(result);
+ // }
+ // } catch (e) {
+ // console.log(e);
+ // }
+ };
+
@action addField = () => {
const newFields: Col[] = this._userCreatedFields.concat([{ title: '', type: TemplateFieldType.UNSET, desc: '', sizes: [] }]);
this._userCreatedFields = newFields;
@@ -515,7 +543,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
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;
});
@@ -555,15 +583,15 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
const brokenDownAssignments: [Template, { [fieldID: number]: Col }][] = [];
Object.entries(assignments).forEach(([tempTitle, assignment]) => {
- const template = templates.filter(t => t.mainField.getTitle() === tempTitle)[0];
+ const template = templates.filter(temp => temp.title === tempTitle)[0];
if (!template) return;
const toObj = Object.entries(assignment).reduce(
(a, [fieldID, colTitle]) => {
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
+ // 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 field
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);
@@ -585,16 +613,24 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
};
generatePresetTemplates = async () => {
- this._dataViz?.updateColDefaults();
+ const templates: Template[] = [];
+
+ if (this.DEBUG_MODE) {
+ templates.push(...this.templateManager.templates);
+ } else {
+ this._dataViz?.updateColDefaults();
+
+ const cols = this.fieldsInfos;
+ templates.push(...this.templateManager.getValidTemplates(cols));
- const cols = this.fieldsInfos;
- const templates = this.templateManager.getValidTemplates(cols);
+ const assignments: [Template, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
- const assignments: [Template, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
+ const renderedTemplatePromises: Promise<Template | undefined>[] = assignments.map(([template, assgns]) => this.applyGPTContentToTemplate(template, assgns));
- const renderedTemplatePromises: Promise<Template | undefined>[] = assignments.map(([template, asns]) => this.applyGPTContentToTemplate(template, asns));
+ await Promise.all(renderedTemplatePromises);
+ }
- await Promise.all(renderedTemplatePromises);
+ templates.forEach(template => template.mainField.initializeDocument({ title: template.title, opts: {}, viewType: ViewType.FREEFORM, tl: [0, 0], br: [900, 900] }, []));
setTimeout(() => {
this.setSuggestedTemplates(templates);
@@ -602,13 +638,13 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
});
};
- renderGPTImageCall = async (template: Template, col: Col, fieldNumber: number): Promise<boolean> => {
+ renderGPTImageCall = async (template: Template, col: Col, fieldNumber: number | undefined): Promise<boolean> => {
const generateAndLoadImage = async (fieldNum: string, column: Col, prompt: string) => {
const url = await this.generateGPTImage(prompt);
- const field: Field = template.getFieldByID(Number(fieldNum));
+ const field: TemplateField = template.getFieldByID(Number(fieldNum));
- field.setContent(url ?? '', FieldContentType.IMAGE);
- field.setTitle(column.title);
+ field.setContent(url ?? '', ViewType.IMG);
+ field.setTitle(col.title);
};
const fieldContent: string = template.compiledContent;
@@ -629,7 +665,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
return true;
};
- renderGPTTextCall = async (template: Template, col: Col, fieldNum: number): Promise<boolean> => {
+ renderGPTTextCall = async (template: Template, col: Col, fieldNum: number | undefined): Promise<boolean> => {
const wordLimit = (size: TemplateFieldSize) => {
switch (size) {
case TemplateFieldSize.TINY:
@@ -656,14 +692,16 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
const res = await gptAPICall(`${++this._callCount}: ${prompt}`, GPTCallType.FILL);
+ // console.log('prompt: ', prompt, ' response: ', res);
+
if (res) {
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 column = this.getColByTitle(title);
+ Object.entries(assignments).forEach(([, /* title */ info]) => {
+ const field: TemplateField = template.getFieldByID(Number(info.number));
+ // const column = this.getColByTitle(title);
- field.setContent(info.content ?? '', FieldContentType.STRING);
- field.setTitle(column.title);
+ field.setContent(info.content ?? '', ViewType.TEXT);
+ field.setTitle(col.title);
});
}
} catch (err) {
@@ -693,16 +731,14 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
});
const processContent = async (content: { [title: string]: string }) => {
- const templateCopy = template.cloneBase();
+ const templateCopy = await template.cloneBase();
fields
.filter(title => title)
.forEach(title => {
const field = templateCopy.getFieldByTitle(title);
- if (field === undefined) {
- return;
- }
- field.setContent(content[title]);
+ if (field === undefined) return;
+ field.setContent(content[title], field.viewType);
});
const gptPromises = this._userCreatedFields
@@ -710,9 +746,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
.map(field => {
const title = field.title;
const templateField = templateCopy.getFieldByTitle(title);
- if (templateField === undefined) {
- return;
- }
+ if (templateField === undefined) return;
const templatefieldID = templateField.getID;
return this.renderGPTTextCall(templateCopy, field, templatefieldID);
@@ -723,9 +757,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
.map(field => {
const title = field.title;
const templateField = templateCopy.getFieldByTitle(title);
- if (templateField === undefined) {
- return;
- }
+ if (templateField === undefined) return;
const templatefieldID = templateField.getID;
return this.renderGPTImageCall(templateCopy, field, templatefieldID);
@@ -735,14 +767,20 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
await Promise.all(imagePromises);
- return templateCopy.getRenderedDoc();
+ this._DOCCC = templateCopy.mainField.renderedDoc;
+ return templateCopy.mainField.renderedDoc;
};
- const promises = rowContents.map(content => processContent(content));
+ let docs: Promise<Doc | undefined>[];
+ if (this.DEBUG_MODE) {
+ docs = [1, 2, 3, 4].map(() => processContent({}));
+ } else {
+ docs = rowContents.map(content => processContent(content));
+ }
- const renderedDocs = await Promise.all(promises);
+ const renderedDocs = await Promise.all(docs);
- this._docsRendering = false;
+ this._docsRendering = false; // removes loading indicator
return renderedDocs;
};
@@ -760,7 +798,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
@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;
@@ -803,7 +841,10 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
className="docCreatorMenu-menu-button section-reveal-options top-right"
onPointerDown={e =>
this.setUpButtonClick(e, () => {
- this._currEditingTemplate && this.updateTemplatePreview(this._currEditingTemplate);
+ if (!this._currEditingTemplate) return;
+ if (this._currEditingTemplate === this._selectedTemplate) {
+ this.updateRenderedPreviewCollection(this._currEditingTemplate);
+ }
this.setExpandedView(undefined);
})
}>
@@ -813,8 +854,8 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
className="docCreatorMenu-menu-button section-reveal-options top-right-lower"
onPointerDown={e =>
this.setUpButtonClick(e, () => {
- this._currEditingTemplate?.resetToBase();
- this.setExpandedView(this._currEditingTemplate);
+ this._currEditingTemplate?.printFieldInfo();
+ /*this._currEditingTemplate?.resetToBase();*/ this.setExpandedView(this._currEditingTemplate);
})
}>
<FontAwesomeIcon icon="arrows-rotate" color="white" />
@@ -827,6 +868,34 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
get templatesPreviewContents() {
const GPTOptions = <div></div>;
+ const previewDoc = (doc: Doc | undefined, template: Template) =>
+ !doc ? null : (
+ <DocumentView
+ Document={doc}
+ isContentActive={emptyFunction} // !!! should be return false
+ addDocument={returnFalse}
+ moveDocument={returnFalse}
+ removeDocument={returnFalse}
+ PanelWidth={() => (this._selectedTemplate === template ? 104 : 111)}
+ PanelHeight={() => (this._selectedTemplate === template ? 104 : 111)}
+ ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
+ renderDepth={1}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ styleProvider={DefaultStyleProvider}
+ addDocTab={this._props.addDocTab}
+ pinToPres={() => undefined}
+ childFilters={returnEmptyFilter}
+ childFiltersByRanges={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ fitContentsToBox={returnFalse}
+ fitWidth={returnFalse}
+ hideDecorations={true}
+ />
+ );
+
+ //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
+
return (
<div className={`docCreatorMenu-templates-view`}>
{this._expandedPreview ? (
@@ -846,10 +915,10 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
<ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
</div>
) : (
- this._suggestedTemplatePreviews.map(({ doc, template }) => (
+ this._suggestedTemplates.map(template => (
<div
+ key={template.toString()}
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)` : '',
@@ -867,28 +936,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
<button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.addUserTemplate(template))}>
<FontAwesomeIcon icon="plus" color="white" />
</button>
- <DocumentView
- Document={doc}
- isContentActive={emptyFunction} // !!! should be return false
- addDocument={returnFalse}
- moveDocument={returnFalse}
- removeDocument={returnFalse}
- PanelWidth={() => (this._selectedTemplate === template ? 104 : 111)}
- PanelHeight={() => (this._selectedTemplate === template ? 104 : 111)}
- ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
- renderDepth={1}
- whenChildContentsActiveChanged={emptyFunction}
- focus={emptyFunction}
- styleProvider={DefaultStyleProvider}
- addDocTab={this._props.addDocTab}
- pinToPres={() => undefined}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- fitContentsToBox={returnFalse}
- fitWidth={returnFalse}
- hideDecorations={true}
- />
+ {previewDoc(template.getRenderedDoc(), template)}
</div>
))
)}
@@ -914,10 +962,10 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
<div className="docCreatorMenu-preview-window empty">
<FontAwesomeIcon icon="plus" color="rgb(160, 160, 160)" />
</div>
- {this._userTemplates.map(({ template, doc }) => (
+ {this._userTemplates.map(template => (
<div
+ key={template.toString()}
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)` : '',
@@ -935,28 +983,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
<button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this.removeUserTemplate(template))}>
<FontAwesomeIcon icon="minus" color="white" />
</button>
- <DocumentView
- Document={doc}
- isContentActive={emptyFunction} // !!! should be return false
- addDocument={returnFalse}
- moveDocument={returnFalse}
- removeDocument={returnFalse}
- PanelWidth={() => (this._selectedTemplate === template ? 104 : 111)}
- PanelHeight={() => (this._selectedTemplate === template ? 104 : 111)}
- ScreenToLocalTransform={() => new Transform(-this._pageX - 5, -this._pageY - 35, 1)}
- renderDepth={1}
- whenChildContentsActiveChanged={emptyFunction}
- focus={emptyFunction}
- styleProvider={DefaultStyleProvider}
- addDocTab={this._props.addDocTab}
- pinToPres={() => undefined}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- fitContentsToBox={returnFalse}
- fitWidth={returnFalse}
- hideDecorations={true}
- />
+ {previewDoc(template.getRenderedDoc(), template)}
</div>
))}
</div>
@@ -1017,11 +1044,9 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
collection._height = verticalSpan;
collection._width = horizontalSpan;
- const layout = this._layout;
- const columns: number = layout.columns ?? this.columnsCount;
- const xGap: number = layout.xMargin;
- const yGap: number = layout.yMargin;
- // const repeat: number = templateInfo.layout.repeat;
+ const columns: number = this._layout.columns ?? this.columnsCount;
+ const xGap: number = this._layout.xMargin;
+ const yGap: number = this._layout.yMargin;
const startX: number = -Number(collection._width) / 2;
const startY: number = -Number(collection._height) / 2;
const docHeight: number = Number(docs[0]._height);
@@ -1070,36 +1095,35 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
updateRenderedDocCollection = () => {
if (!this._fullyRenderedDocs) return;
- const { horizontalSpan, verticalSpan } = this.previewInfo;
-
const collectionFactory = (): ((docs: Doc[], options: DocumentOptions) => Doc) => {
switch (this._layout.type) {
- case LayoutType.CAROUSEL3D:
- return Docs.Create.Carousel3DDocument;
- case LayoutType.FREEFORM:
- return Docs.Create.FreeformDocument;
- case LayoutType.CARD:
- return Docs.Create.CardDeckDocument;
- case LayoutType.MASONRY:
- return Docs.Create.MasonryDocument;
- case LayoutType.CAROUSEL:
- return Docs.Create.CarouselDocument;
- default:
- return Docs.Create.FreeformDocument;
- }
+ case LayoutType.CAROUSEL3D: return Docs.Create.Carousel3DDocument;
+ case LayoutType.FREEFORM: return Docs.Create.FreeformDocument;
+ case LayoutType.CARD: return Docs.Create.CardDeckDocument;
+ case LayoutType.MASONRY: return Docs.Create.MasonryDocument;
+ case LayoutType.CAROUSEL: return Docs.Create.CarouselDocument;
+ default: return Docs.Create.FreeformDocument;
+ } // prettier-ignore
};
- const collection: Doc = collectionFactory()(this._fullyRenderedDocs, {
+ const collection = collectionFactory()(this._fullyRenderedDocs, {
isDefaultTemplateDoc: true,
- _height: verticalSpan,
- _width: horizontalSpan,
title: 'title',
backgroundColor: 'gray',
+ x: 200,
+ y: 200,
+ _width: 4000,
+ _height: 4000,
});
this.applyLayout(collection, this._fullyRenderedDocs);
this._renderedDocCollection = collection;
+
+ const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
+ mainCollection.addDocument(collection);
+
+ console.log('changed to: ', collection);
};
layoutPreviewContents = () => {
@@ -1212,9 +1236,9 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
emptyFunction,
undoable(clickEv => {
clickEv.stopPropagation();
- if (!this._selectedTemplate) return;
+ if (!this._selectedTemplate || !this._selectedTemplate.getRenderedDoc()) return;
const layout: DataVizTemplateLayout = {
- template: this._selectedTemplate.getRenderedDoc(),
+ template: this._selectedTemplate.getRenderedDoc()!,
layout: { type: this._layout.type, xMargin: this._layout.xMargin, yMargin: this._layout.yMargin, repeat: 0 },
columns: this.columnsCount,
rows: this.rowsCount,
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
deleted file mode 100644
index c5254c17d..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/DynamicField.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import { Doc } from "../../../../../../fields/Doc";
-import { Docs } from "../../../../../documents/Documents";
-import { Field, FieldDimensions, FieldSettings, ViewType } from "./Field";
-import { FieldUtils } from "./FieldUtils";
-import { StaticField } from "./StaticField";
-
-export class DynamicField implements Field {
- private subfields: Field[] = [];
-
- private id: number;
- private settings: FieldSettings;
- private title: string = '';
-
- private parent: Field;
- private dimensions: FieldDimensions;
-
- constructor(settings: FieldSettings, id: number, parent?: Field) {
- 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]}};
- } else {
- this.parent = parent;
- this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions);
- }
- this.subfields = this.setupSubfields();
- }
-
- setContent = () => { return };
- getContent = () => { return '' };
-
- setTitle = (title: string) => { this.title = title };
- getTitle = () => { return this.title };
-
- 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 ?? '';
- }
-
- matches = (): 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
- const r = (coords.br[0] * this.dimensions.height) / 2;
- const b = coords.br[1] * this.dimensions.width / 2; //prettier-ignore
- const width = r - l;
- const height = b - t;
- const coord = { x: l, y: t };
- return { width, height, coord };
- };
-
- renderedDoc = (): Doc => {
- let doc: Doc;
- switch (this.settings.viewType) {
- case ViewType.CAROUSEL3D:
- doc = Docs.Create.Carousel3DDocument(this.subfields.map(field => field.renderedDoc()), {
- title: this.title,
- });
- FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings);
- return doc;
- case ViewType.FREEFORM:
- doc = Docs.Create.FreeformDocument(this.subfields.map(field => field.renderedDoc()), {
- title: this.title,
- });
- 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
deleted file mode 100644
index ea9b566b3..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/Field.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { Doc } from "../../../../../../fields/Doc";
-import { Col } from "../DocCreatorMenu";
-import { TemplateFieldSize, TemplateFieldType } from "../TemplateBackend";
-
-export enum FieldContentType {
- STRING = 'string',
- IMAGE = 'image',
-}
-
-export enum ViewType {
- CAROUSEL3D = 'carousel3d',
- FREEFORM = 'freeform',
- STATIC = 'static',
- DEC = 'decoration'
-}
-
-export type FieldDimensions = {
- width: number;
- height: number;
- coord: {x: number, y: number};
-}
-
-export interface FieldOpts {
- backgroundColor?: string;
- color?: string;
- cornerRounding?: number;
- borderWidth?: string;
- borderColor?: string;
- contentXCentering?: 'h-left' | 'h-center' | 'h-right';
- contentYCentering?: 'top' | 'center' | 'bottom';
- opacity?: number;
- rotation?: number;
- 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/FieldUtils.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx
deleted file mode 100644
index 3886774d2..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/FieldUtils.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { Doc } from "../../../../../../fields/Doc";
-import { ComputedField, ScriptField } from "../../../../../../fields/ScriptField";
-import { Col } from "../DocCreatorMenu";
-import { TemplateFieldSize, TemplateFieldType, TemplateLayouts } from "../TemplateBackend";
-import { FieldDimensions, FieldSettings } from "./Field";
-
-export class FieldUtils {
- public static getLocalDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentDimensions: FieldDimensions): FieldDimensions => {
- const l = (coords.tl[0] * parentDimensions.width) / 2;
- const t = coords.tl[1] * parentDimensions.height / 2; //prettier-ignore
- const r = (coords.br[0] * parentDimensions.width) / 2;
- const b = coords.br[1] * parentDimensions.height / 2; //prettier-ignore
- const width = r - l;
- const height = b - t;
- const coord = { x: l, y: t };
- return { width, height, coord };
- };
-
- public static applyBasicOpts = (doc: Doc, parentDimensions: FieldDimensions, settings: FieldSettings, oldDoc?: Doc) => {
- const opts = settings.opts;
- doc.isDefaultTemplateDoc = oldDoc ? oldDoc.isDefaultTemplateDoc : true;
- doc._layout_hideScroll = oldDoc ? oldDoc._layout_hideScroll : true;
- doc.x = oldDoc ? oldDoc.x : parentDimensions.coord.x;
- doc.y = oldDoc ? oldDoc.y : parentDimensions.coord.y;
- doc._height = oldDoc ? oldDoc.height : parentDimensions.height;
- doc._width = oldDoc ? oldDoc.width : parentDimensions.width;
- doc.backgroundColor = oldDoc ? oldDoc.backgroundColor : opts.backgroundColor ?? '';
- doc._layout_borderRounding = !opts.cornerRounding ? '0px' : ScriptField.MakeFunction(`${opts.cornerRounding} * this.width + 'px'`);
- doc.borderColor = oldDoc ? oldDoc.borderColor : opts.borderColor;
- doc.borderWidth = oldDoc ? oldDoc.borderWidth : opts.borderWidth;
- doc.opacity = oldDoc ? oldDoc.opacity : opts.opacity;
- doc._rotation = oldDoc ? oldDoc._rotation : opts.rotation;
- doc.hCentering = oldDoc ? oldDoc.hCentering : opts.contentXCentering;
- doc.nativeWidth = parentDimensions.width;
- doc.nativeHeight = parentDimensions.height;
- doc._layout_nativeDimEditable = true;
- };
-
- public static calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
- const words: string[] = text.split(/\s+/).filter(Boolean);
-
- let currFontSize = 1;
- let rowsCount = 1;
- let currTextHeight = currFontSize * rowsCount * 2;
-
- while (currTextHeight <= contHeight) {
- let wordIndex = 0;
- let currentRowWidth = 0;
- let wordsInCurrRow = 0;
- rowsCount = 1;
-
- while (wordIndex < words.length) {
- const word = words[wordIndex];
- const wordWidth = word.length * currFontSize * 0.7;
-
- if (currentRowWidth + wordWidth <= contWidth) {
- currentRowWidth += wordWidth;
- ++wordsInCurrRow;
- } else {
- if (words.length !== 1 && words.length > wordsInCurrRow) {
- rowsCount++;
- currentRowWidth = wordWidth;
- wordsInCurrRow = 1;
- } else {
- break;
- }
- }
-
- wordIndex++;
- }
-
- currTextHeight = rowsCount * currFontSize * 2;
-
- currFontSize += 1;
- }
-
- return currFontSize - 1;
- };
-} \ 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 47b43f051..000000000
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes/StaticField.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import { Doc } from "../../../../../../fields/Doc";
-import { Docs } from "../../../../../documents/Documents";
-import { Col } from "../DocCreatorMenu";
-import { DynamicField } from "./DynamicField";
-import { FieldUtils } from "./FieldUtils";
-import { Field, FieldContentType, FieldDimensions, FieldSettings, ViewType } from "./Field";
-
-export class StaticField {
- private content: string;
- private contentType: FieldContentType | undefined;
- private subfields: Field[] = [];
- private renderedDocument: Doc;
-
- private id: number;
- private title: string = '';
-
- private settings: FieldSettings;
-
- private parent: Field;
- private dimensions: FieldDimensions;
-
- 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);
- this.content = '';
- this.subfields = this.setupSubfields();
- this.renderedDocument = this.updateRenderedDoc();
- };
-
- 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 getDimensions() { return this.dimensions };
- get getID() { return this.id };
- get getViewType() { return this.settings.viewType };
-
- get getDescription(): string {
- return this.settings.description ?? '';
- }
-
- renderedDoc = () => {
- return this.renderedDocument;
- }
-
- setContent = (newContent: string, type?: FieldContentType) => {
- this.content = newContent;
- if (type) this.contentType = type;
- this.updateRenderedDoc(this.renderedDocument);
- };
- getContent() { return this.content };
-
- setTitle = (title: string) => {
- this.title = title;
- this.renderedDocument.title = title;
- this.updateRenderedDoc(this.renderedDocument);
- };
- getTitle = () => { return this.title };
-
- applyAttributes = (field: Field) => { //!!! can be updated later for more robust clonign; this is all ythat's needed now
- field.setTitle(this.title);
- field.setContent('', this.contentType);
- field.updateRenderedDoc(this.renderedDoc());
- }
-
- 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.FREEFORM || type === ViewType.CAROUSEL3D) {
- field = new DynamicField(fieldSettings, id, this);
- } else {
- field = new StaticField(fieldSettings, this, id);
- };
-
- fields.push(field);
- });
- return fields;
- };
-
- 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<number> = [];
-
- 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:
- 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, String(this.content), true)}`
- });
- FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc);
- break;
- case FieldContentType.IMAGE:
- doc = Docs.Create.ImageDocument(String(this.content), {
- title: this.title,
- _layout_fitWidth: false,
- });
- FieldUtils.applyBasicOpts(doc, this.dimensions, this.settings, oldDoc);
- break;
- }
-
- 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.ts
index 0a5097d4a..ef6867e32 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts
@@ -1,56 +1,69 @@
-import { Doc, FieldType } from "../../../../../fields/Doc";
-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 { makeAutoObservable } from 'mobx';
+import { Col } from './DocCreatorMenu';
+import { DynamicField } from './TemplateFieldTypes/DynamicField';
+import { TemplateField, FieldSettings } from './TemplateFieldTypes/TemplateField';
+import { TemplateLayouts } from './TemplateBackend';
export class Template {
-
mainField: DynamicField;
- settings: FieldSettings;
+ private settings: FieldSettings;
constructor(templateInfo: FieldSettings) {
- this.mainField = this.setupMainField(templateInfo);
+ makeAutoObservable(this);
this.settings = templateInfo;
+ this.mainField = this.setupMainField(templateInfo);
}
- 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(); };
-
- cloneBase = () => {
- const clone: Template = new Template(this.settings);
- clone.allFields.forEach(field => {
- const matchingField: Field = this.allFields.filter(f => f.getID === field.getID)[0];
- matchingField.applyAttributes(field);
- })
- return clone;
+ get childFields(): TemplateField[] {
+ return this.mainField.getSubfields;
+ }
+ get allFields(): TemplateField[] {
+ return this.mainField.getAllSubfields;
+ }
+ get contentFields(): TemplateField[] {
+ return this.allFields.filter(field => field.isContentField);
+ }
+ get doc() {
+ return this.mainField.renderedDoc;
+ }
+ get title() {
+ return this.mainField.getTitle();
}
- getRenderedDoc = () => {
- const doc: Doc = this.mainField.renderedDoc();
- this.contentFields.forEach(field => {
- const title: string = field.getTitle();
- const val: FieldType = field.getContent() as FieldType;
- if (!title || !val) return;
- doc[title] = val;
+ cleanup = () => {
+ //dispose each subfields disposers, etc.
+ };
+
+ cloneBase = async (): Promise<Template> => {
+ const clone: Template = new Template(TemplateLayouts.BasicSettings);
+ clone.mainField = (await this.mainField.makeClone(undefined)) as unknown as DynamicField;
+ // clone.mainField.renderedDoc._width = this.mainField.renderedDoc._width;
+ // clone.mainField.renderedDoc._height = this.mainField.renderedDoc._height;
+ return clone;
+ };
+
+ printFieldInfo = () => {
+ this.allFields.forEach(field => {
+ const doc = field.renderedDoc;
+ console.log('title: ', field.getTitle(), ' width: ', doc?.width);
});
- return doc;
- }
+ };
- getFieldByID = (id: number): Field => {
+ getRenderedDoc = () => {
+ return this.doc;
+ };
+
+ getFieldByID = (id: number): TemplateField => {
return this.allFields.filter(field => field.getID === id)[0];
- }
+ };
getFieldByTitle = (title: string) => {
return this.allFields.filter(field => field.getTitle() === title)[0];
- }
+ };
setupMainField = (templateInfo: FieldSettings) => {
- return new DynamicField(templateInfo, 1);
- }
+ return DynamicField.Create(templateInfo, 1);
+ };
get descriptionSummary(): string {
let summary: string = '';
@@ -68,23 +81,10 @@ export class Template {
return summary;
}
- renderUpdates = () => {
- this.allFields.forEach(field => {
- field.updateRenderedDoc(field.renderedDoc());
- });
- };
-
- resetToBase = () => {
- this.allFields.forEach(field => {
- field.updateRenderedDoc();
- })
- }
-
isValidTemplate = (cols: Col[]) => {
- const matches: number[][] = this.getMatches(cols);
- const maxMatches: number = this.maxMatches(matches);
+ const maxMatches = this.maxMatches(this.getMatches(cols));
return maxMatches === this.contentFields.length;
- }
+ };
getMatches = (cols: Col[]): number[][] => {
const numFields = this.contentFields.length;
@@ -96,11 +96,11 @@ export class Template {
.map(() => []);
this.contentFields.forEach((field, i) => {
- matches[i] = (field.matches(cols));
+ matches[i] = field.matches(cols);
});
return matches;
- }
+ };
maxMatches = (matches: number[][]) => {
if (matches.length === 0) return 0;
@@ -135,5 +135,4 @@ export class Template {
return count;
};
-
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.ts
index d3282eda3..9b0fac3a6 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateBackend.ts
@@ -1,5 +1,4 @@
-import { FieldSettings, ViewType } from "./FieldTypes/Field";
-import { } from "./FieldTypes/StaticField";
+import { FieldSettings, ViewType } from './TemplateFieldTypes/TemplateField';
export enum TemplateFieldType {
TEXT = 'text',
@@ -20,6 +19,14 @@ export class TemplateLayouts {
return Object.values(TemplateLayouts);
}
+ public static BasicSettings: FieldSettings = {
+ title: 'template_framework',
+ tl: [0, 0],
+ br: [400, 700],
+ viewType: ViewType.FREEFORM,
+ opts: {},
+ };
+
public static FourField001: FieldSettings = {
title: 'fourfield001',
tl: [0, 0],
@@ -27,7 +34,7 @@ export class TemplateLayouts {
viewType: ViewType.FREEFORM,
opts: {
backgroundColor: '#C0B887',
- cornerRounding: .05,
+ _layout_borderRounding: '.05',
//borderColor: '#6B461F',
//borderWidth: '12',
},
@@ -41,9 +48,9 @@ export class TemplateLayouts {
description: 'A title field for very short text that contextualizes the content.',
opts: {
backgroundColor: 'transparent',
- color: '#F1F0E9',
- contentXCentering: 'h-center',
- fontBold: true,
+ text_fontColor: '#F1F0E9',
+ hCentering: 'h-center',
+ contentBold: true,
},
},
{
@@ -54,9 +61,9 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'The main focus of the template; could be an image, long text, etc.',
opts: {
- cornerRounding: .05,
+ _layout_borderRounding: '.05',
borderColor: '#8F5B25',
- borderWidth: '6',
+ borderWidth: 6,
backgroundColor: '#CECAB9',
},
},
@@ -69,8 +76,8 @@ export class TemplateLayouts {
description: 'A caption for field #2, very short text.',
opts: {
backgroundColor: 'transparent',
- contentXCentering: 'h-center',
- color: '#F1F0E9',
+ hCentering: 'h-center',
+ text_fontColor: '#F1F0E9',
},
},
{
@@ -81,9 +88,9 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium-sized field for medium/long text.',
opts: {
- cornerRounding: .05,
+ _layout_borderRounding: '.05',
borderColor: '#8F5B25',
- borderWidth: '6',
+ borderWidth: 6,
backgroundColor: '#CECAB9',
},
},
@@ -93,7 +100,7 @@ export class TemplateLayouts {
public static FourField002: FieldSettings = {
title: 'fourfield002',
viewType: ViewType.FREEFORM,
- tl: [0,0],
+ tl: [0, 0],
br: [425, 778],
opts: {
backgroundColor: '#242425',
@@ -107,10 +114,10 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus.',
opts: {
- borderWidth: '8',
+ borderWidth: 8,
borderColor: '#F8E71C',
backgroundColor: '#242425',
- color: 'white',
+ text_fontColor: 'white',
},
},
{
@@ -122,9 +129,9 @@ export class TemplateLayouts {
description: 'A tiny field for just a word or two of plain text.',
opts: {
backgroundColor: 'transparent',
- color: 'white',
- contentXCentering: 'h-center',
- fontTransform: 'uppercase',
+ text_fontColor: 'white',
+ hCentering: 'h-center',
+ text_transform: 'uppercase',
},
},
{
@@ -136,9 +143,9 @@ export class TemplateLayouts {
description: 'A tiny field for just a word or two of plain text.',
opts: {
backgroundColor: 'transparent',
- color: 'white',
- contentXCentering: 'h-center',
- fontTransform: 'uppercase',
+ text_fontColor: 'white',
+ hCentering: 'h-center',
+ text_transform: 'uppercase',
},
},
{
@@ -149,9 +156,9 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium to large-sized field suitable for longer text that should contextualize field 1.',
opts: {
- borderWidth: '8',
+ borderWidth: 8,
borderColor: '#F8E71C',
- color: 'white',
+ text_fontColor: 'white',
backgroundColor: '#242425',
},
},
@@ -161,7 +168,7 @@ export class TemplateLayouts {
br: [-0.525, 0.075],
opts: {
backgroundColor: '#F8E71C',
- rotation: 45,
+ _rotation: 45,
},
},
{
@@ -170,7 +177,7 @@ export class TemplateLayouts {
br: [-0.2175, 0.0245],
opts: {
backgroundColor: '#F8E71C',
- rotation: 45,
+ _rotation: 45,
},
},
{
@@ -179,7 +186,7 @@ export class TemplateLayouts {
br: [0.045, 0.0245],
opts: {
backgroundColor: '#F8E71C',
- rotation: 45,
+ _rotation: 45,
},
},
{
@@ -188,7 +195,7 @@ export class TemplateLayouts {
br: [0.3075, 0.0245],
opts: {
backgroundColor: '#F8E71C',
- rotation: 45,
+ _rotation: 45,
},
},
{
@@ -197,7 +204,7 @@ export class TemplateLayouts {
br: [0.8, 0.075],
opts: {
backgroundColor: '#F8E71C',
- rotation: 45,
+ _rotation: 45,
},
},
],
@@ -266,8 +273,8 @@ export class TemplateLayouts {
public static FourField004: FieldSettings = {
title: 'fourfield04',
viewType: ViewType.FREEFORM,
- tl: [0,0],
- br: [414,583],
+ tl: [0, 0],
+ br: [414, 583],
opts: {
backgroundColor: '#6CCAF0',
//borderColor: '#1088C3',
@@ -283,9 +290,9 @@ export class TemplateLayouts {
description: 'A tiny field for just a word or two of plain text.',
opts: {
backgroundColor: '#E2B4F5',
- borderWidth: '9',
+ borderWidth: 9,
borderColor: '#9222F1',
- contentXCentering: 'h-center',
+ hCentering: 'h-center',
},
},
{
@@ -297,9 +304,9 @@ export class TemplateLayouts {
description: 'A tiny field for just a word or two of plain text.',
opts: {
backgroundColor: '#F5B4DD',
- borderWidth: '9',
+ borderWidth: 9,
borderColor: '#E260F3',
- contentXCentering: 'h-center',
+ hCentering: 'h-center',
},
},
{
@@ -310,7 +317,7 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A large to huge field for visual content that is the main content of the template.',
opts: {
- borderWidth: '16',
+ borderWidth: 16,
borderColor: '#A2BD77',
},
},
@@ -322,7 +329,7 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
description: 'A medium to large field for text that describes the visual content above',
opts: {
- borderWidth: '9',
+ borderWidth: 9,
borderColor: '#F0D601',
backgroundColor: '#F3F57D',
},
@@ -334,7 +341,7 @@ export class TemplateLayouts {
opts: {
backgroundColor: 'transparent',
borderColor: '#007C0C',
- borderWidth: '10',
+ borderWidth: 10,
},
},
],
@@ -343,218 +350,229 @@ export class TemplateLayouts {
public static FourField005: FieldSettings = {
title: 'fourfield05',
viewType: ViewType.FREEFORM,
- tl: [0,0],
- br: [400,550],
+ tl: [0, 0],
+ br: [400, 550],
opts: {
backgroundColor: '#95A575',
},
subfields: [
{
viewType: ViewType.STATIC,
- tl: [-0.9, -.925],
- br: [-.075, -.775],
+ tl: [-0.9, -0.925],
+ br: [-0.075, -0.775],
types: [TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
description: 'A small text field for a title or word(s) that categorize the rest of the content.',
opts: {
borderColor: '#3B4A2C',
- borderWidth: '8',
- contentXCentering: "h-center",
+ borderWidth: 8,
+ hCentering: 'h-center',
backgroundColor: '#B8DC90',
},
},
{
viewType: ViewType.STATIC,
- tl: [.075, -.925],
- br: [.9, -.775],
+ tl: [0.075, -0.925],
+ br: [0.9, -0.775],
types: [TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
description: 'A small text field for a title that categorizes the rest of the content.',
opts: {
borderColor: '#3B4A2C',
- borderWidth: '8',
- contentXCentering: "h-center",
+ borderWidth: 8,
+ hCentering: 'h-center',
backgroundColor: '#B8DC90',
},
},
{
viewType: ViewType.DEC,
- tl: [-.82, -.4],
- br: [-.5, -.2],
+ tl: [-0.82, -0.4],
+ br: [-0.5, -0.2],
opts: {
backgroundColor: '#94B058',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.STATIC,
- tl: [-0.66, -.65],
- br: [0.66, .25],
+ tl: [-0.66, -0.65],
+ br: [0.66, 0.25],
types: [TemplateFieldType.VISUAL],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
description: 'A medium to large field in the center of the template, for the main visual content.',
opts: {
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
backgroundColor: '#B8DC90',
},
},
{
viewType: ViewType.STATIC,
- tl: [-.875, .425],
- br: [0.875, .925],
+ tl: [-0.875, 0.425],
+ br: [0.875, 0.925],
types: [TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
description: 'A medium to large field at the bottom of the template, for the main text content.',
opts: {
borderColor: '#3B4A2C',
- borderWidth: '8',
- contentXCentering: "h-center",
+ borderWidth: 8,
+ hCentering: 'h-center',
backgroundColor: '#B8DC90',
},
},
{
viewType: ViewType.DEC,
- tl: [-1.1, -.62],
- br: [-.9, -.5],
+ tl: [-1.1, -0.62],
+ br: [-0.9, -0.5],
opts: {
backgroundColor: '#7A9D31',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.DEC,
tl: [-1.1, 0],
- br: [-.9, .15],
+ br: [-0.9, 0.15],
opts: {
backgroundColor: '#94B058',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.DEC,
- tl: [-.93, -.265],
- br: [-.715, -.125],
+ tl: [-0.93, -0.265],
+ br: [-0.715, -0.125],
opts: {
backgroundColor: '#728745',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.DEC,
- tl: [.7, -.45],
- br: [.85, -.3],
+ tl: [0.7, -0.45],
+ br: [0.85, -0.3],
opts: {
backgroundColor: '#7A9D31',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.DEC,
- tl: [.8, .03],
- br: [1.2, .33],
+ tl: [0.8, 0.03],
+ br: [1.2, 0.33],
opts: {
backgroundColor: '#728745',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
{
viewType: ViewType.DEC,
- tl: [.875, -.13],
- br: [1.2, .12],
+ tl: [0.875, -0.13],
+ br: [1.2, 0.12],
opts: {
backgroundColor: '#94B058',
borderColor: '#3B4A2C',
- borderWidth: '8',
+ borderWidth: 8,
},
},
- ]
- }
+ ],
+ };
public static FourFieldCarousel: FieldSettings = {
title: 'title_fourfieldcarousel',
viewType: ViewType.FREEFORM,
- tl:[0,0],
- br:[500, 600],
+ tl: [0, 0],
+ br: [500, 600],
opts: {
- backgroundColor: '#DDD3A9',
+ backgroundColor: '#D7CBAB',
},
subfields: [
{
viewType: ViewType.STATIC,
- tl: [-0.8, -.9],
- br: [0.8, -.5],
+ tl: [-0.8, -0.9],
+ br: [0.8, -0.5],
types: [TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
description: 'A small text field for a title that categorizes the rest of the content.',
opts: {
- borderColor: 'yellow',
- borderWidth: '8',
- contentXCentering: "h-center",
+ hCentering: 'h-center',
backgroundColor: 'transparent',
+ text_transform: 'uppercase',
},
},
{
viewType: ViewType.CAROUSEL3D,
- tl: [-0.9, -.3],
- br: [0.9, .9],
+ tl: [-0.9, -0.5],
+ br: [0.9, 0.25],
opts: {
- borderColor: 'yellow',
- borderWidth: '8',
- backgroundColor: 'transparent',
+ borderColor: '#847F69',
+ borderWidth: 8,
+ backgroundColor: '#C8BA94',
},
subfields: [
{
viewType: ViewType.STATIC,
- tl: [-.3, -.6],
- br: [.3, .6],
+ tl: [-0.4, -0.6],
+ br: [0.4, 0.6],
types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium to large field for content that will share central focus with other content in the carousel.',
opts: {
- borderColor: 'yellow',
- borderWidth: '8',
+ //borderColor: 'yellow',
+ //borderWidth: '8',
},
},
{
viewType: ViewType.STATIC,
- tl: [-.3, -.6],
- br: [.3, .6],
+ tl: [-0.4, -0.6],
+ br: [0.4, 0.6],
types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium to large field for content that will share central focus with other content in the carousel.',
opts: {
- borderColor: 'black',
- borderWidth: '8',
+ //borderColor: 'black',
+ //borderWidth: '8',
},
},
{
viewType: ViewType.STATIC,
- tl: [-.3, -.6],
- br: [.3, .6],
+ tl: [-0.4, -0.6],
+ br: [0.4, 0.6],
types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium to large field for content that will share central focus with other content in the carousel.',
opts: {
- borderColor: 'yellow',
- borderWidth: '8',
+ //borderColor: 'yellow',
+ //borderWidth: '8',
},
},
- ]
+ ],
},
- ]
- }
+ {
+ viewType: ViewType.STATIC,
+ tl: [-0.9, 0.35],
+ br: [0.9, 0.9],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+ description: 'A medium text field for a description of the content in the carousel.',
+ opts: {
+ hCentering: 'h-center',
+ backgroundColor: 'transparent',
+ },
+ },
+ ],
+ };
public static ThreeField001: FieldSettings = {
title: 'threefield001',
viewType: ViewType.FREEFORM,
- tl: [0,0],
+ tl: [0, 0],
br: [575, 770],
opts: {
backgroundColor: '#DDD3A9',
@@ -567,23 +585,23 @@ export class TemplateLayouts {
description: 'A medium to large field for visual content that is the central focus.',
opts: {
borderColor: 'yellow',
- borderWidth: '8',
+ borderWidth: 8,
backgroundColor: '#DDD3A9',
- rotation: 45,
+ _rotation: 45,
},
subfields: [
{
- viewType: ViewType.STATIC,
- tl: [-1.25, -1.25],
- br: [1.25, 1.25],
- types: [TemplateFieldType.VISUAL],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: 'A medium to large field for visual content that is the central focus.',
- opts: {
- rotation: -45,
+ viewType: ViewType.STATIC,
+ tl: [-1.25, -1.25],
+ br: [1.25, 1.25],
+ types: [TemplateFieldType.VISUAL],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+ description: 'A medium to large field for visual content that is the central focus.',
+ opts: {
+ _rotation: -45,
+ },
},
- },
- ]
+ ],
},
{
viewType: ViewType.STATIC,
@@ -594,7 +612,7 @@ export class TemplateLayouts {
description: 'A very small text field for one to a few words. A good caption for the image.',
opts: {
backgroundColor: 'transparent',
- contentXCentering: 'h-center',
+ hCentering: 'h-center',
},
},
{
@@ -606,7 +624,7 @@ export class TemplateLayouts {
description: 'A medium to large text field for a thorough description of the image. ',
opts: {
backgroundColor: 'transparent',
- color: 'white',
+ text_fontColor: 'white',
},
},
{
@@ -615,18 +633,18 @@ export class TemplateLayouts {
br: [1.8, -0.66],
opts: {
backgroundColor: '#CEB155',
- rotation: 45,
+ _rotation: 45,
},
subfields: [
{
viewType: ViewType.DEC,
- tl: [-1, -.7],
- br: [1, -.625],
+ tl: [-1, -0.7],
+ br: [1, -0.625],
opts: {
backgroundColor: 'yellow',
},
},
- ]
+ ],
},
{
viewType: ViewType.FREEFORM,
@@ -634,18 +652,18 @@ export class TemplateLayouts {
br: [-0.2, -0.66],
opts: {
backgroundColor: '#CEB155',
- rotation: 135,
+ _rotation: 135,
},
subfields: [
{
viewType: ViewType.DEC,
- tl: [-1, -.7],
- br: [1, -.625],
+ tl: [-1, -0.7],
+ br: [1, -0.625],
opts: {
backgroundColor: 'yellow',
},
},
- ]
+ ],
},
{
viewType: ViewType.FREEFORM,
@@ -653,18 +671,18 @@ export class TemplateLayouts {
br: [1.66, 1.25],
opts: {
backgroundColor: '#CEB155',
- rotation: 135,
+ _rotation: 135,
},
subfields: [
{
viewType: ViewType.DEC,
- tl: [-1, -.7],
- br: [1, -.625],
+ tl: [-1, -0.7],
+ br: [1, -0.625],
opts: {
backgroundColor: 'yellow',
},
},
- ]
+ ],
},
{
viewType: ViewType.FREEFORM,
@@ -672,18 +690,18 @@ export class TemplateLayouts {
br: [-0.33, 1.25],
opts: {
backgroundColor: '#CEB155',
- rotation: 45,
+ _rotation: 45,
},
subfields: [
{
viewType: ViewType.DEC,
- tl: [-1, -.7],
- br: [1, -.625],
+ tl: [-1, -0.7],
+ br: [1, -0.625],
opts: {
backgroundColor: 'yellow',
},
},
- ]
+ ],
},
],
};
@@ -691,7 +709,7 @@ export class TemplateLayouts {
public static ThreeField002: FieldSettings = {
title: 'threefield002',
viewType: ViewType.FREEFORM,
- tl: [0,0],
+ tl: [0, 0],
br: [477, 662],
opts: {
backgroundColor: '#9E9C95',
@@ -705,7 +723,7 @@ export class TemplateLayouts {
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
description: 'A medium to large visual field for the main content of the template',
opts: {
- borderWidth: '15',
+ borderWidth: 15,
borderColor: '#E0E0DA',
},
},
@@ -718,10 +736,10 @@ export class TemplateLayouts {
description: 'A very small text field for one to a few words. The content should represent a general categorization of the image.',
opts: {
backgroundColor: 'transparent',
- color: '#AF0D0D',
- fontTransform: 'uppercase',
- fontBold: true,
- contentXCentering: 'h-left',
+ text_fontColor: '#AF0D0D',
+ text_transform: 'uppercase',
+ contentBold: true,
+ hCentering: 'h-left',
},
},
{
@@ -733,8 +751,8 @@ export class TemplateLayouts {
description: 'A very small text field for one to a few words. The content should contextualize field 2.',
opts: {
backgroundColor: 'transparent',
- color: 'black',
- contentXCentering: 'h-right',
+ text_fontColor: 'black',
+ hCentering: 'h-right',
},
},
{
@@ -748,5 +766,3 @@ export class TemplateLayouts {
],
};
}
-
-
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DecorationField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DecorationField.ts
new file mode 100644
index 000000000..4f5ad89b6
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DecorationField.ts
@@ -0,0 +1,11 @@
+import { DynamicField } from './DynamicField';
+import { FieldSettings, TemplateField } from './TemplateField';
+
+export class DecorationField extends DynamicField {
+ private constructor(settings: FieldSettings, parent?: TemplateField, id: number = 1) {
+ super(settings, parent, id);
+ }
+ static Create(settings: FieldSettings, id: number | undefined, parent?: TemplateField) {
+ return DynamicField.Create(settings, id, parent);
+ }
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts
new file mode 100644
index 000000000..0917093b1
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts
@@ -0,0 +1,164 @@
+import { reaction } from 'mobx';
+import { IDisposer } from 'mobx-utils';
+import { Doc, DocListCast } from '../../../../../../fields/Doc';
+import { DocData } from '../../../../../../fields/DocSymbols';
+import { List } from '../../../../../../fields/List';
+import { NumCast } from '../../../../../../fields/Types';
+import { Docs } from '../../../../../documents/Documents';
+import { DocumentType } from '../../../../../documents/DocumentTypes';
+import { FieldSettings, TemplateField, ViewType } from './TemplateField';
+
+export class DynamicField extends TemplateField {
+ protected _disposers: { [name: string]: IDisposer } = {};
+ protected _subfields: TemplateField[] | undefined;
+
+ protected constructor(settings: FieldSettings, parent?: TemplateField, id: number = 1) {
+ super(settings, parent, id);
+ }
+ static Create(settings: FieldSettings, id: number | undefined, parent?: TemplateField) {
+ const field = new DynamicField(settings, parent, id);
+ field._subfields = settings.subfields?.map((fieldSettings, index) => TemplateField.initField(fieldSettings, index, field)) || [];
+ field._renderDoc = field.initializeDocument(settings, field._subfields);
+ field._disposers.fieldList = reaction(() => DocListCast(field._renderDoc?.[Doc.LayoutFieldKey(field._renderDoc)]), field.handleFieldUpdate);
+ return field;
+ }
+
+ get getSubfields(): TemplateField[] {
+ return this._subfields ?? [];
+ }
+ get getAllSubfields() {
+ return (
+ this._subfields?.reduce((fields, field) => {
+ fields.push(field, ...((field as DynamicField).getAllSubfields ?? []));
+ return fields;
+ }, [] as TemplateField[]) ?? []
+ );
+ }
+
+ setSubFields = (fields: TemplateField[]) => (this._subfields = fields);
+
+ handleFieldUpdate = (newDocsList: Doc[]) => {
+ const currRenderedDocs = new Set(this._subfields?.filter(field => field.renderedDoc).map(field => field.renderedDoc!));
+ newDocsList.forEach(doc => !currRenderedDocs.has(doc) && this.addFieldFromDoc(doc));
+ currRenderedDocs.forEach(doc => {
+ if (!newDocsList.includes(doc)) {
+ this._subfields?.forEach(field => field.renderedDoc === doc && this.removeField(field));
+ }
+ });
+ };
+
+ addFieldFromDoc = (doc: Doc) => {
+ const par = this._renderDoc;
+ const settings: FieldSettings = {
+ tl: [Number(doc._x) / NumCast(par?._width, 1), Number(doc?._y) / NumCast(par?._height, 1)],
+ br: [(Number(doc._x) + Number(doc._width)) / NumCast(par?._width, 1), (Number(doc._y) + Number(doc._height)) / NumCast(par?._height, 1)],
+ viewType: doc.type === DocumentType.COL ? ViewType.FREEFORM : ViewType.STATIC,
+ opts: {},
+ };
+
+ this._subfields?.push(TemplateField.initField(settings, this._subfields?.length ?? 0, this));
+ };
+
+ addField = (field: TemplateField) => {
+ if (!this._subfields?.includes(field)) {
+ this._subfields?.push(field);
+ // Doc.SetContainer(field.Document, this.Document);
+ }
+ };
+
+ dispose = () => Object.values(this._disposers).forEach(disposer => disposer?.());
+
+ removeField = (field: TemplateField) => {
+ // var childDocs: Doc[] = DocListCast(this.Document[Doc.LayoutFieldKey(this.Document)]);
+ // this.Document[Doc.LayoutFieldKey(this.Document)] = new List<Doc>([...childDocs.splice(childDocs.indexOf(field.Document), 1)]);
+ this._subfields?.splice(this._subfields?.indexOf(field), 1);
+ (field as DynamicField).dispose?.();
+ };
+
+ // implement Field's abstract method for replacing a subfield with a new one
+ exchangeFields(newField: TemplateField, oldField: TemplateField) {
+ this._subfields?.splice(this._subfields?.indexOf(oldField), 1, newField);
+ }
+
+ get isContentField(): boolean {
+ return false;
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ setContent(content: string, type: ViewType) {}
+
+ getContent = () => '';
+
+ addChildToDocument = (doc: Doc) => this._renderDoc && Doc.SetContainer(doc, this._renderDoc);
+
+ matches = (): Array<number> => [];
+
+ async makeClone(parent?: DynamicField): Promise<TemplateField> {
+ const clone = (await super.makeClone(parent)) as unknown as DynamicField;
+ if (this._subfields) {
+ clone._subfields = await Promise.all(this._subfields.map(async cloneField => await cloneField.makeClone(clone)));
+ }
+ clone._renderDoc && (clone._renderDoc[DocData].data = new List<Doc>(clone._subfields?.filter(sub => sub.renderedDoc).map(sub => sub.renderedDoc!) ?? []));
+ return clone;
+ }
+
+ initializeDocument = (settings: FieldSettings, subFields: TemplateField[]) => {
+ const renderedSubfields = subFields?.filter(field => field.renderedDoc).map(field => field.renderedDoc!) ?? [];
+ settings.opts.title = settings.title;
+ switch (settings.viewType) {
+ case ViewType.CAROUSEL3D: return Docs.Create.Carousel3DDocument(renderedSubfields, settings.opts);
+ case ViewType.FREEFORM:
+ default: return Docs.Create.FreeformDocument(renderedSubfields, settings.opts);
+ } // prettier-ignore
+ };
+}
+
+// export class DynamicField extends Field {
+// protected subfields: Field[];
+
+// protected Document!: Doc;
+
+// constructor(settings: FieldSettings, id: number, parent?: Field) {
+// super(settings, id, parent);
+// this.subfields = this.setupSubfields(this);
+// this.initializeDocument();
+// }
+
+// setContent = (content: string, type: ViewType) => { return };
+// getContent = () => { return '' };
+// get isContentField(): boolean { return false };
+
+// addChildToDocument = (doc: Doc) => {
+// Doc.SetContainer(doc, this.Document);
+// }
+
+// matches = (cols: Col[]): Array<number> => {
+// return [];
+// }
+
+// initializeDocument = (): Doc => {
+// let doc: Doc;
+// const renderedSubfields: Doc[] = this.subfields.map(field => field.renderedDoc);
+// switch (this.settings.viewType) {
+// case ViewType.CAROUSEL3D:
+// doc = Docs.Create.Carousel3DDocument(renderedSubfields, {
+// title: this.title,
+// });
+// break;
+// case ViewType.FREEFORM:
+// doc = Docs.Create.FreeformDocument(renderedSubfields, {
+// title: this.title,
+// });
+// break;
+// default:
+// doc = Docs.Create.FreeformDocument(renderedSubfields, {
+// title: this.title,
+// });
+// break;
+// }
+
+// this.Document = doc;
+// return doc;
+// }
+
+// }
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/StaticContentField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/StaticContentField.ts
new file mode 100644
index 000000000..b8839efab
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/StaticContentField.ts
@@ -0,0 +1,72 @@
+import { DocData } from '../../../../../../fields/DocSymbols';
+import { RichTextField } from '../../../../../../fields/RichTextField';
+import { ImageField } from '../../../../../../fields/URLField';
+import { Docs } from '../../../../../documents/Documents';
+import { FieldSettings, TemplateField, ViewType } from './TemplateField';
+import { TemplateFieldUtils } from './TemplateFieldUtils';
+
+export abstract class StaticContentField extends TemplateField {
+ protected _content: string = '';
+
+ getContent = () => this._content ?? 'unset';
+ get isContentField(): boolean {
+ return true;
+ }
+}
+
+export class ImageTemplateField extends StaticContentField {
+ private constructor(settings: FieldSettings, parent?: TemplateField, id: number = 1) {
+ super(settings, parent, id);
+ }
+ static Create(settings: FieldSettings, id: number | undefined, parent: TemplateField | undefined) {
+ const field = new ImageTemplateField(settings, parent, id);
+ field._renderDoc = field.initializeDocument(settings);
+ return field;
+ }
+
+ setContent(url: string, type?: ViewType) {
+ super.setContent(url, type);
+
+ if (type === ViewType.IMG || type === undefined) {
+ this._renderDoc && (this._renderDoc[DocData].data = new ImageField(url));
+ this._content = url;
+ } else {
+ this.changeFieldType(type).setContent(url, type);
+ }
+ }
+
+ initializeDocument = (settings: FieldSettings) => {
+ settings.opts.title = settings.title;
+ settings.opts._layout_fitWidth = false;
+
+ return Docs.Create.ImageDocument('', settings.opts);
+ };
+}
+
+export class TextTemplateField extends StaticContentField {
+ private constructor(settings: FieldSettings, parent?: TemplateField, id: number = 1) {
+ super(settings, parent, id);
+ }
+ static Create(settings: FieldSettings, id: number, parent?: TemplateField) {
+ const field = new TextTemplateField(settings, parent, id);
+ field._renderDoc = field.initializeDocument(settings);
+ field._renderDoc.text_fontSize = `${TemplateFieldUtils.calculateFontSize(field._dimensions?.width ?? 10, field._dimensions?.height ?? 10, '', true)}`;
+ return field;
+ }
+ setContent(text: string, type?: ViewType) {
+ super.setContent(text, type);
+
+ if (type === ViewType.TEXT || type === undefined) {
+ this._content = text;
+ this._renderDoc && (this._renderDoc[DocData].text = RichTextField.textToRtf(text));
+ } else {
+ this.changeFieldType(type).setContent(text, type);
+ }
+ }
+
+ initializeDocument = (settings: FieldSettings | undefined) => {
+ const opts = settings?.opts;
+ opts && (opts.title = settings?.title ?? '');
+ return Docs.Create.TextDocument('', opts);
+ };
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts
new file mode 100644
index 000000000..318bffde5
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts
@@ -0,0 +1,159 @@
+/* eslint-disable no-use-before-define */
+import { computed } from 'mobx';
+import { Doc } from '../../../../../../fields/Doc';
+import { DocData } from '../../../../../../fields/DocSymbols';
+import { Copy } from '../../../../../../fields/FieldSymbols';
+import { ObjectField } from '../../../../../../fields/ObjectField';
+import { DocumentOptions } from '../../../../../documents/Documents';
+import { Col } from '../DocCreatorMenu';
+import { TemplateFieldSize, TemplateFieldType } from '../TemplateBackend';
+
+export abstract class TemplateField {
+ /**
+ * Creates and initializes a new TemplateField based on the settings and parameters
+ *
+ * implemented in FieldUtils and assigned in main (to avoid import cycles)
+ *
+ * @param settings - specification of the field type and other parameters
+ * @param index -
+ * @param parent - TemplateField that contains the new field
+ * @param sameId -
+ * @returns TemplateField
+ */
+ static initField: (settings: FieldSettings | undefined, index: number | undefined, parent: TemplateField | undefined, sameId?: boolean) => TemplateField;
+
+ protected _parent?: TemplateField;
+ protected _id: number;
+ protected _title: string = '';
+ protected _settings: FieldSettings;
+ protected _renderDoc: Doc | undefined;
+ protected _dimensions: FieldDimensions | undefined;
+
+ constructor(settings: FieldSettings, parent?: TemplateField, id: number = 1) {
+ this._id = id;
+ this._parent = parent;
+ this._settings = settings;
+ this._title = settings.title ?? '';
+ this._dimensions = this.getLocalDimensions(this._settings, this._parent?.getDimensions);
+ this.applyBasicOpts(this._dimensions, settings);
+ return this;
+ }
+
+ get renderedDoc() {
+ return this._renderDoc;
+ }
+ get getDimensions() {
+ return this._dimensions;
+ }
+ get getID() {
+ return this._id;
+ }
+ get getDescription(): string {
+ return this._settings?.description ?? '';
+ }
+ get viewType(): ViewType | undefined {
+ return this._settings?.viewType;
+ }
+
+ setTitle = (title: string) => {
+ this._title = title;
+ this._renderDoc && (this._renderDoc.title = title);
+ };
+ getTitle = () => this._title;
+
+ abstract get isContentField(): boolean;
+ setContent(content: string, type?: ViewType) {
+ this._settings && (this._settings.viewType = type ?? this._settings.viewType);
+ }
+
+ abstract getContent(): string;
+
+ async makeClone(parent?: TemplateField): Promise<TemplateField> {
+ const clone = TemplateField.initField(this._settings, this._id, parent, true); // create a value for this.Document/subfields that we want to ignore
+ clone._renderDoc = this._renderDoc ? (await Doc.MakeClone(this._renderDoc)).clone : undefined;
+ clone._title = this._title;
+ clone._dimensions = this._dimensions;
+ return clone;
+ }
+
+ @computed get documentOptions(): DocumentOptions {
+ const opts: DocumentOptions = {};
+ Object.assign(opts, this._renderDoc?.[DocData]);
+ Object.entries(opts).forEach(([key, field]) => {
+ Object.assign(opts, { [key]: field instanceof Object ? ObjectField.MakeCopy(field) : field[Copy]() });
+ });
+ return opts;
+ }
+ exchangeFields(newField: TemplateField, oldField: TemplateField) {
+ throw new Error('Only DynamicField can exchange fields.' + newField._title + ' ' + oldField._title);
+ }
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ changeFieldType = (newType: ViewType): TemplateField => {
+ const newField = TemplateField.initField(this._settings, this._id, this._parent, true);
+ this._parent?.exchangeFields(newField, this);
+ return newField;
+ };
+
+ matches = (cols: Col[]): number[] => {
+ const colMatchesField = (col: Col) => (this._settings?.sizes?.some(size => col.sizes?.includes(size)) && this._settings.types?.includes(col.type)) ?? false;
+
+ const matches: Array<number> = [];
+ cols.forEach((col, v) => colMatchesField(col) && matches.push(v));
+ return matches;
+ };
+
+ private getLocalDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentDimensions?: FieldDimensions): FieldDimensions => {
+ if (!parentDimensions) {
+ return { width: coords.br[0] - coords.tl[0], height: coords.br[1] - coords.tl[1], coord: { x: coords.tl[0], y: coords.tl[1] } };
+ }
+ const l = (coords.tl[0] * parentDimensions.width) / 2;
+ const t = coords.tl[1] * parentDimensions.height / 2; //prettier-ignore
+ const r = (coords.br[0] * parentDimensions.width) / 2;
+ const b = coords.br[1] * parentDimensions.height / 2; //prettier-ignore
+ return { width: r-l, height: b-t, coord: { x: l, y: t } }; //prettier-ignore
+ };
+
+ private applyBasicOpts = (dimensions: FieldDimensions, settings: FieldSettings | undefined) => {
+ const opts: DocumentOptions = settings?.opts ?? {};
+ opts.isDefaultTemplateDoc ??= true;
+ opts._layout_hideScroll ??= true;
+ opts.x ??= dimensions.coord.x;
+ opts.y ??= dimensions.coord.y;
+ opts._height ??= dimensions.height;
+ opts._width ??= dimensions.width;
+ opts._nativeWidth ??= dimensions.width;
+ opts._nativeHeight ??= dimensions.height;
+ opts._layout_nativeDimEditable ??= true;
+ };
+}
+
+export type FieldSettings = {
+ tl: [number, number];
+ br: [number, number];
+ opts: DocumentOptions;
+ viewType: ViewType;
+ title?: string;
+ subfields?: FieldSettings[];
+ types?: TemplateFieldType[];
+ sizes?: TemplateFieldSize[];
+ description?: string;
+};
+
+export enum ViewType {
+ CAROUSEL3D = 'carousel3d',
+ FREEFORM = 'freeform',
+ STATIC = 'static',
+ DEC = 'decoration',
+ IMG = 'image',
+ TEXT = 'text',
+}
+
+export type FieldDimensions = {
+ width: number;
+ height: number;
+ coord: { x: number; y: number };
+};
+
+export type FieldTree = {
+ node: { field: TemplateField; subfields: FieldTree[] };
+};
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateFieldUtils.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateFieldUtils.ts
new file mode 100644
index 000000000..c38d769cd
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateFieldUtils.ts
@@ -0,0 +1,71 @@
+import { DecorationField } from './DecorationField';
+import { DynamicField } from './DynamicField';
+import { ImageTemplateField, TextTemplateField } from './StaticContentField';
+import { FieldSettings, TemplateField, ViewType } from './TemplateField';
+
+export class TemplateFieldUtils {
+ /**
+ * Creates and initializes a new TemplateField based on the settings and parameters
+ *
+ * implements Field.initField ... see main.tsx
+ *
+ * @param settings - specification of the field type and other parameters
+ * @param index -
+ * @param parent - TemplateField that contains the new field
+ * @param sameId -
+ * @returns TemplateField
+ */
+ public static initField = (settings: FieldSettings, index: number, parent: TemplateField | undefined, sameId: boolean = false): TemplateField => {
+ const id = sameId ? index : parent ? Number(`${parent.getID}${index}`) : 1;
+ switch (settings?.viewType) {
+ case ViewType.FREEFORM:
+ case ViewType.CAROUSEL3D: return DynamicField.Create(settings, id, parent);
+ case ViewType.IMG: return ImageTemplateField.Create(settings, id, parent);
+ case ViewType.TEXT: return TextTemplateField.Create(settings, id, parent);
+ case ViewType.DEC: return DecorationField.Create(settings, id, parent);
+ default: return TextTemplateField.Create(settings, id, parent);
+ } // prettier-ignore
+ };
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ public static calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
+ const words: string[] = text.split(/\s+/).filter(Boolean);
+
+ let currFontSize = 1;
+ let rowsCount = 1;
+ let currTextHeight = currFontSize * rowsCount * 2;
+
+ while (currTextHeight <= contHeight) {
+ let wordIndex = 0;
+ let currentRowWidth = 0;
+ let wordsInCurrRow = 0;
+ rowsCount = 1;
+
+ while (wordIndex < words.length) {
+ const word = words[wordIndex];
+ const wordWidth = word.length * currFontSize * 0.7;
+
+ if (currentRowWidth + wordWidth <= contWidth) {
+ currentRowWidth += wordWidth;
+ ++wordsInCurrRow;
+ } else {
+ if (words.length !== 1 && words.length > wordsInCurrRow) {
+ rowsCount++;
+ currentRowWidth = wordWidth;
+ wordsInCurrRow = 1;
+ } else {
+ break;
+ }
+ }
+
+ wordIndex++;
+ }
+
+ currTextHeight = rowsCount * currFontSize * 2;
+
+ currFontSize += 1;
+ }
+
+ return currFontSize - 1;
+ };
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.ts
index 50ae4d72a..1959cf9d6 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateManager.ts
@@ -1,12 +1,13 @@
-import { Col } from "./DocCreatorMenu";
-import { FieldSettings } from "./FieldTypes/Field";
-import { Template } from "./Template";
+import { makeAutoObservable } from 'mobx';
+import { Col } from './DocCreatorMenu';
+import { FieldSettings } from './TemplateFieldTypes/TemplateField';
+import { Template } from './Template';
export class TemplateManager {
-
templates: Template[] = [];
constructor(templateSettings: FieldSettings[]) {
+ makeAutoObservable(this);
this.templates = this.initializeTemplates(templateSettings);
}
@@ -14,9 +15,19 @@ export class TemplateManager {
const initializedTemplates: Template[] = [];
templateSettings.forEach(settings => initializedTemplates.push(new Template(settings)));
return initializedTemplates;
- }
+ };
getValidTemplates = (cols: Col[]): Template[] => {
+ console.log('called in manager with templates: ', this.templates);
return this.templates.filter(template => template.isValidTemplate(cols));
- }
-} \ No newline at end of file
+ };
+
+ addTemplate = (newTemplate: Template) => {
+ this.templates.push(newTemplate);
+ };
+
+ removeTemplate = (template: Template) => {
+ this.templates.splice(this.templates.indexOf(template), 1);
+ template.cleanup();
+ };
+}
diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx
index c672bc718..f92037e93 100644
--- a/src/client/views/smartdraw/DrawingFillHandler.tsx
+++ b/src/client/views/smartdraw/DrawingFillHandler.tsx
@@ -14,7 +14,7 @@ import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions, Firefl
const DashDropboxId = '2m86iveqdr9vzsa';
export class DrawingFillHandler {
- static drawingToImage = async (drawing: Doc, strength: number, user_prompt: string, styleDoc?: Doc) => {
+ static drawingToImage = async (drawing: Doc, strength: number, user_prompt: string, styleDoc?: Doc, flexDimensions?: boolean) => {
const docData = drawing[DocData];
const tags = StrListCast(docData.tags).map(tag => tag.slice(1));
const styles = tags.filter(tag => FireflyStylePresets.has(tag));
@@ -44,7 +44,7 @@ export class DrawingFillHandler {
return imageUrlToBase64(structureUrl)
.then(gptDescribeImage)
.then((prompt, newPrompt = user_prompt || prompt) =>
- Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: `${newPrompt}`, width: dims.width, height: dims.height, structureUrl, strength, presets: styles, styleUrl })
+ Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: `${newPrompt}`, width: flexDimensions ? aspectRatio * 2000 : dims.width, height: flexDimensions ? (1 - aspectRatio) * 2000 : dims.height, structureUrl, strength, presets: styles, styleUrl })
.then(res => {
const genratedDocs = DocCast(drawing.ai_firefly_generatedDocs) ?? Docs.Create.MasonryDocument([], { _width: 400, _height: 400 });
drawing[DocData].ai_firefly_generatedDocs = genratedDocs;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index fc89dcbe7..bb7df75fc 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -573,7 +573,7 @@ export namespace Doc {
if (!skipUndefineds || value !== undefined) {
// Do we want to filter out undefineds?
if (typeof value === 'object' && 'values' in value) {
- console.log(value);
+ //console.log(value);
}
doc[key] = value;
}