aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-09-30 18:26:59 -0400
committerbobzel <zzzman@gmail.com>2024-09-30 18:26:59 -0400
commit431a03690ed131e4bb925cec465d91adfb0d9421 (patch)
treebaeb2fc8d7518646f988406b6a3d67a677f42865
parentcf45abf8ada938caddb226c825166d4acdee3086 (diff)
fixed so that you can't set the author field from the schema view. fixed schema view to not trigger cell updates after cells have been unmounted (e.g, so that dragging a tab over a schema vew doesn't crash)
-rw-r--r--src/client/views/collections/collectionSchema/SchemaCellField.tsx190
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx2115
2 files changed, 1226 insertions, 1079 deletions
diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
index 065544ac9..e26dd9646 100644
--- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
@@ -1,22 +1,22 @@
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from "mobx";
-import { ObservableReactComponent } from "../../ObservableReactComponent";
-import { observer } from "mobx-react";
-import { OverlayView } from "../../OverlayView";
-import { DocumentIconContainer } from "../../nodes/DocumentIcon";
-import React, { FormEvent } from "react";
-import { FieldView, FieldViewProps } from "../../nodes/FieldView";
-import { ObjectField } from "../../../../fields/ObjectField";
-import { Doc } from "../../../../fields/Doc";
-import { DocumentView } from "../../nodes/DocumentView";
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { observer } from 'mobx-react';
+import { OverlayView } from '../../OverlayView';
+import { DocumentIconContainer } from '../../nodes/DocumentIcon';
+import React, { FormEvent } from 'react';
+import { FieldView, FieldViewProps } from '../../nodes/FieldView';
+import { ObjectField } from '../../../../fields/ObjectField';
+import { Doc } from '../../../../fields/Doc';
+import { DocumentView } from '../../nodes/DocumentView';
/**
* The SchemaCellField renders text in schema cells while the user is editing, and updates the
* contents of the field based on user input. It handles some cell-side logic for equations, such
* as how equations are broken up within the text.
- *
- * The current implementation parses innerHTML to create spans based on the text in the cell.
+ *
+ * The current implementation parses innerHTML to create spans based on the text in the cell.
* A more robust/safer approach would directly add elements in the react structure, but this
- * has been challenging to implement.
+ * has been challenging to implement.
*/
export interface SchemaCellFieldProps {
@@ -26,7 +26,7 @@ export interface SchemaCellFieldProps {
oneLine?: boolean;
Document: Doc;
fieldKey: string;
- refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined};
+ refSelectModeInfo: { enabled: boolean; currEditing: SchemaCellField | undefined };
highlightCells?: (text: string) => void;
GetValue(): string | undefined;
SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean;
@@ -35,7 +35,6 @@ export interface SchemaCellFieldProps {
@observer
export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldProps> {
-
private _disposers: { [name: string]: IReactionDisposer } = {};
private _inputref: HTMLDivElement | null = null;
private _unrenderedContent: string = '';
@@ -48,7 +47,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
constructor(props: SchemaCellFieldProps) {
super(props);
makeObservable(this);
- setTimeout(() => {
+ setTimeout(() => {
this._unrenderedContent = this._props.GetValue() ?? '';
this.setContent(this._unrenderedContent);
}); //must be moved to end of batch or else other docs aren't loaded, so render as d-1 in function
@@ -56,9 +55,11 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
get docIndex(){return DocumentView.getDocViewIndex(this._props.Document);} // prettier-ignore
- get selfRefPattern() {return `d${this.docIndex}.${this._props.fieldKey}`};
+ get selfRefPattern() {
+ return `d${this.docIndex}.${this._props.fieldKey}`;
+ }
- @computed get lastCharBeforeCursor(){
+ @computed get lastCharBeforeCursor() {
const pos = this.cursorPosition;
const content = this._unrenderedContent;
const text = this._unrenderedContent.substring(0, pos ?? content.length);
@@ -90,7 +91,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
this._props.highlightCells?.(this._unrenderedContent);
this.setContent(this._unrenderedContent);
setTimeout(() => this.setCursorPosition(this._unrenderedContent.length));
- }
+ }
});
} else {
this._overlayDisposer?.();
@@ -104,10 +105,11 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
this._disposers.fieldUpdate = reaction(
() => this._props.GetValue(),
fieldVal => {
+ console.log('Update: ' + this._props.Document.title, this._props.fieldKey, fieldVal);
this._unrenderedContent = fieldVal ?? '';
this.finalizeEdit(false, false, false);
}
- )
+ );
}
componentDidUpdate(prevProps: Readonly<SchemaCellFieldProps>) {
@@ -120,7 +122,10 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
});
}
+ _unmounted = false;
componentWillUnmount(): void {
+ this._unmounted = true;
+ console.log('Unmount: ' + this._props.Document.title, this._props.fieldKey);
this._overlayDisposer?.();
Object.values(this._disposers).forEach(disposer => disposer?.());
this.finalizeEdit(false, true, false);
@@ -129,7 +134,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
generateSpan = (text: string, cell: HTMLDivElement | undefined) => {
const selfRef = text === this.selfRefPattern;
return `<span style="text-decoration: ${selfRef ? 'underline' : 'none'}; text-decoration-color: red; color: ${selfRef ? 'gray' : cell?.style.borderTop.replace('2px solid', '')}">${text}</span>`;
- }
+ };
makeSpans = (content: string) => {
let chunkedText = content;
@@ -144,28 +149,28 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
const cell = this._props.getCells(match[0]);
if (cell.length) {
matches.push(match[0]);
- cells.set(match[0], cell[0])
+ cells.set(match[0], cell[0]);
}
}
matches.forEach((match: string) => {
chunkedText = chunkedText.replace(match, this.generateSpan(match, cells.get(match)));
- })
+ });
return chunkedText;
- }
+ };
/**
- * Sets the rendered content of the cell to save user inputs.
+ * Sets the rendered content of the cell to save user inputs.
* @param content the content to set
* @param restoreCursorPos whether the cursor should be set back to where it was rather than the 0th index; should usually be true
*/
- @action
+ @action
setContent = (content: string, restoreCursorPos?: boolean) => {
const pos = this.cursorPosition;
this._displayedContent = this.makeSpans(content);
restoreCursorPos && setTimeout(() => this.setCursorPosition(pos));
- }
+ };
//Called from schemaview when a cell is selected to add a reference to the equation
/**
@@ -181,7 +186,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
const newText = atPos ? content.slice(0, robustPos) + text + content.slice(cursorPos ?? content.length) : this._unrenderedContent.concat(text);
this.onChange(undefined, newText);
setTimeout(() => this.setCursorPosition(robustPos + text.length));
- }
+ };
@action
setIsFocused = (value: boolean) => {
@@ -195,32 +200,31 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
*/
get cursorPosition() {
const selection = window.getSelection();
- if (!selection || selection.rangeCount === 0 || !this._inputref) return null;
-
+ if (!selection || selection.rangeCount === 0 || !this._inputref) return null;
+
const range = selection.getRangeAt(0);
const adjRange = range.cloneRange();
-
+
adjRange.selectNodeContents(this._inputref);
adjRange.setEnd(range.startContainer, range.startOffset);
- return adjRange.toString().length;
+ return adjRange.toString().length;
}
-
setCursorPosition = (position: number | null) => {
const selection = window.getSelection();
- if (!selection || position === null || !this._inputref) return;
-
+ if (!selection || position === null || !this._inputref) return;
+
const range = document.createRange();
range.setStart(this._inputref, 0);
range.collapse(true);
-
+
let currentPos = 0;
const setRange = (nodes: NodeList) => {
for (let i = 0; i < nodes.length; ++i) {
const node = nodes[i];
- if (node.nodeType === Node.TEXT_NODE) {
+ if (node.nodeType === Node.TEXT_NODE) {
if (!node.textContent) return;
const nextPos = currentPos + node.textContent.length;
if (position <= nextPos) {
@@ -231,11 +235,10 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
return true;
}
currentPos = nextPos;
-
- } else if ((node.nodeType === Node.ELEMENT_NODE) && (setRange(node.childNodes))) return true;
+ } else if (node.nodeType === Node.ELEMENT_NODE && setRange(node.childNodes)) return true;
}
return false;
- }
+ };
setRange(this._inputref.childNodes);
};
@@ -265,7 +268,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
const properties = this._props.refSelectModeInfo;
properties.enabled = enabled;
properties.currEditing = enabled ? this : undefined;
- }
+ };
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
@@ -289,9 +292,12 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
e.stopPropagation();
this._editing = false;
break;
- case 'ArrowUp': case 'ArrowDown': case 'ArrowLeft': case 'ArrowRight': // prettier-ignore
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight': // prettier-ignore
e.stopPropagation();
- setTimeout(() => this.setupRefSelect(this.refSelectConditionMet), 0)
+ setTimeout(() => this.setupRefSelect(this.refSelectConditionMet), 0);
break;
case ' ':
e.stopPropagation();
@@ -300,13 +306,16 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
setTimeout(() => {
this.setContent(this._unrenderedContent);
setTimeout(() => this.setCursorPosition(cursorPos));
- }
- , 0);
+ }, 0);
break;
case 'u': // for some reason 'u' otherwise exits the editor
e.stopPropagation();
break;
- case 'Shift': case 'Alt': case 'Meta': case 'Control': case ':': // prettier-ignore
+ case 'Shift':
+ case 'Alt':
+ case 'Meta':
+ case 'Control':
+ case ':': // prettier-ignore
break;
// eslint-disable-next-line no-fallthrough
default:
@@ -323,66 +332,63 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
};
@action
- finalizeEdit(shiftDown: boolean, lostFocus: boolean, enterKey: boolean) {
+ finalizeEdit = (shiftDown: boolean, lostFocus: boolean, enterKey: boolean) => {
+ if (this._unmounted) {
+ return;
+ }
if (this._unrenderedContent.replace(this.selfRefPattern, '') !== this._unrenderedContent) {
- this._dependencyMessageShown ? this._dependencyMessageShown = false :
- alert(`Circular dependency detected. Please update the field at ${this.selfRefPattern}.`)
+ if (this._dependencyMessageShown) {
+ this._dependencyMessageShown = false;
+ } else alert(`Circular dependency detected. Please update the field at ${this.selfRefPattern}.`);
this._dependencyMessageShown = true;
return;
}
this.setContent(this._unrenderedContent);
-
- if (this._props.SetValue(this._unrenderedContent, shiftDown, enterKey)) {
- this._editing = false;
- } else {
- this._editing = false;
- !lostFocus &&
- setTimeout(
- action(() => {
- this._editing = true;
- }),
- 0
- );
+
+ if (!this._props.SetValue(this._unrenderedContent, shiftDown, enterKey) && !lostFocus) {
+ setTimeout(action(() => (this._editing = true)));
}
- }
+ this._editing = false;
+ };
staticDisplay = () => {
- return <span className='editableView-static'>
- {
- // eslint-disable-next-line react/jsx-props-no-spreading
- this._props.fieldContents ? <FieldView {...this._props.fieldContents}/> : ''
- }
- </span>
- }
+ return <span className="editableView-static">{this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : ''}</span>;
+ };
renderEditor = () => {
return (
- <div
- contentEditable
- className='schemaField-editing'
- ref={r => { this._inputref = r; }}
- style={{ cursor: 'text', outline: 'none', overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }}
- onBlur={() => {this._props.refSelectModeInfo.enabled ? setTimeout(() => {this.setIsFocused(true)}, 1000) : this.finalizeEdit(false, true, false)}}
- autoFocus
- onInput={this.onChange}
- onKeyDown={this.onKeyDown}
- onPointerDown={e => {e.stopPropagation(); setTimeout(() => this.setupRefSelect(this.refSelectConditionMet), 0)}} //timeout callback ensures that refSelectMode is properly set
- onClick={e => e.stopPropagation}
- onPointerUp={e => e.stopPropagation}
- onPointerMove={e => {e.stopPropagation(); e.preventDefault()}}
- dangerouslySetInnerHTML={{ __html: this._displayedContent }}
- >
- </div>
+ <div
+ contentEditable
+ className="schemaField-editing"
+ ref={r => {
+ this._inputref = r;
+ }}
+ style={{ cursor: 'text', outline: 'none', overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20 }}
+ onBlur={() => (this._props.refSelectModeInfo.enabled ? setTimeout(() => this.setIsFocused(true), 1000) : this.finalizeEdit(false, true, false))}
+ autoFocus
+ onInput={this.onChange}
+ onKeyDown={this.onKeyDown}
+ onPointerDown={e => {
+ e.stopPropagation();
+ setTimeout(() => this.setupRefSelect(this.refSelectConditionMet), 0);
+ }} //timeout callback ensures that refSelectMode is properly set
+ onClick={e => e.stopPropagation}
+ onPointerUp={e => e.stopPropagation}
+ onPointerMove={e => {
+ e.stopPropagation();
+ e.preventDefault();
+ }}
+ dangerouslySetInnerHTML={{ __html: this._displayedContent }}></div>
);
- }
+ };
render() {
const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n');
- if ((this._editing && gval !== undefined)) {
+ if (this._editing && gval !== undefined) {
return <div className={`editableView-container-editing${this._props.oneLine ? '-oneLine' : ''}`}>{this.renderEditor()}</div>;
- } else return (
- this._props.contents instanceof ObjectField ? null : (
+ } else
+ return this._props.contents instanceof ObjectField ? null : (
<div
className={`editableView-container-editing${this._props.oneLine ? '-oneLine' : ''}`}
style={{
@@ -393,8 +399,6 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
onClick={this.onClick}>
{this.staticDisplay()}
</div>
- )
- );
+ );
}
-
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
index 5d5c35dce..32aded9de 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
@@ -1,50 +1,42 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { Colors } from 'browndash-components';
+import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import { IDisposer } from 'mobx-utils';
import * as React from 'react';
-import { ClientUtils, returnAll, returnFalse, returnNone, returnOne, returnZero, setupMoveUpEvents } from '../../../../ClientUtils';
+import ReactLoading from 'react-loading';
+import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc';
-import { DocCast, ImageCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { Id } from '../../../../fields/FieldSymbols';
+import { DocCast, ImageCast, StrCast } from '../../../../fields/Types';
import { ImageField } from '../../../../fields/URLField';
-import { emptyFunction } from '../../../../Utils';
+import { Networking } from '../../../Network';
+import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
+import { Docs } from '../../../documents/Documents';
+import { DragManager } from '../../../util/DragManager';
+import { MakeTemplate } from '../../../util/DropConverter';
import { SnappingManager } from '../../../util/SnappingManager';
import { UndoManager, undoable } from '../../../util/UndoManager';
+import { LightboxView } from '../../LightboxView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
import { DocumentView, DocumentViewInternal } from '../DocumentView';
+import { FieldViewProps } from '../FieldView';
+import { OpenWhere } from '../OpenWhere';
import { DataVizBox } from './DataVizBox';
import './DocCreatorMenu.scss';
-import { Id } from '../../../../fields/FieldSymbols';
-import { Colors, IconButton, Size } from 'browndash-components';
-import { MakeTemplate } from '../../../util/DropConverter';
-import { DragManager } from '../../../util/DragManager';
-import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
-import { Docs } from '../../../documents/Documents';
-import { OpenWhere } from '../OpenWhere';
-import { IDisposer } from 'mobx-utils';
-import { LightboxView } from '../../LightboxView';
-import ReactLoading from 'react-loading';
-import { CollectionStackingView } from '../../collections/CollectionStackingView';
-import { FieldViewProps } from '../FieldView';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
-import { dropActionType } from '../../../util/DropActionTypes';
-import { ImageBox } from '../ImageBox';
-import { a } from '@react-spring/web';
-import { RichTextMenu } from '../formattedText/RichTextMenu';
-import e from 'cors';
-import { Networking } from '../../../Network';
export enum LayoutType {
- Stacked = 'stacked',
- Grid = 'grid',
- Row = 'row',
- Column = 'column',
- Custom = 'custom'
+ Stacked = 'stacked',
+ Grid = 'grid',
+ Row = 'row',
+ Column = 'column',
+ Custom = 'custom',
}
@observer
export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
-
static Instance: DocCreatorMenu;
private _disposers: { [name: string]: IDisposer } = {};
@@ -54,13 +46,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
@observable _templateDocs: Doc[] = [];
@observable _selectedTemplate: Doc | undefined = undefined;
@observable _columns: Col[] = [];
- @observable _selectedCols: {title: string, type: string, desc: string}[] | undefined = [];
+ @observable _selectedCols: { title: string; type: string; desc: string }[] | undefined = [];
- @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns?: number, repeat: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, repeat: 0};
+ @observable _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.Grid, yMargin: 0, xMargin: 0, repeat: 0 };
@observable _layoutPreview: boolean = true;
@observable _layoutPreviewScale: number = 1;
@observable _savedLayouts: DataVizTemplateLayout[] = [];
- @observable _expandedPreview: {icon: ImageField, doc: Doc} | undefined = undefined;
+ @observable _expandedPreview: { icon: ImageField; doc: Doc } | undefined = undefined;
@observable _suggestedTemplates: Doc[] = [];
@observable _GPTOpt: boolean = false;
@@ -76,7 +68,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
@observable _hoveredLayoutPreview: number | undefined = undefined;
@observable _mouseX: number = -1;
@observable _mouseY: number = -1;
- @observable _startPos?: {x: number, y: number};
+ @observable _startPos?: { x: number; y: number };
@observable _shouldDisplay: boolean = false;
@observable _menuContent: 'templates' | 'options' | 'saved' | 'dashboard' = 'templates';
@@ -87,10 +79,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
@observable _snapPt: any;
@observable _resizeHdlId: string = '';
@observable _resizing: boolean = false;
- @observable _offset: {x: number, y: number} = {x: 0, y: 0};
+ @observable _offset: { x: number; y: number } = { x: 0, y: 0 };
@observable _resizeUndo: UndoManager.Batch | undefined = undefined;
- @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined};
- @observable _menuDimensions: {width: number, height: number} = {width: 400, height: 400};
+ @observable _initDimensions: { width: number; height: number; x?: number; y?: number } = { width: 300, height: 400, x: undefined, y: undefined };
+ @observable _menuDimensions: { width: number; height: number } = { width: 400, height: 400 };
@observable _editing: boolean = false;
constructor(props: any) {
@@ -100,32 +92,40 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
//setTimeout(() => this.generateTemplates(''));
}
- @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz };
- @action setTemplateDocs = (docs: Doc[]) => {this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc)};
- @action setGSuggestedTemplates = (docs: Doc[]) => {this._suggestedTemplates = docs};
+ @action setDataViz = (dataViz: DataVizBox) => {
+ this._dataViz = dataViz;
+ };
+ @action setTemplateDocs = (docs: Doc[]) => {
+ this._templateDocs = docs.map(doc => (doc.annotationOn ? DocCast(doc.annotationOn) : doc));
+ };
+ @action setGSuggestedTemplates = (docs: Doc[]) => {
+ this._suggestedTemplates = docs;
+ };
@computed get docsToRender() {
return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : [];
}
- @computed get rowsCount(){
+ @computed get rowsCount() {
switch (this._layout.type) {
- case LayoutType.Row: case LayoutType.Stacked:
+ case LayoutType.Row:
+ case LayoutType.Stacked:
return 1;
case LayoutType.Column:
return this.docsToRender.length;
case LayoutType.Grid:
return Math.ceil(this.docsToRender.length / (this._layout.columns ?? 1)) ?? 0;
- default:
+ default:
return 0;
}
}
- @computed get columnsCount(){
+ @computed get columnsCount() {
switch (this._layout.type) {
case LayoutType.Row:
return this.docsToRender.length;
- case LayoutType.Column: case LayoutType.Stacked:
+ case LayoutType.Column:
+ case LayoutType.Stacked:
return 1;
case LayoutType.Grid:
return this._layout.columns ?? 0;
@@ -140,31 +140,33 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
@computed get fieldsInfos(): Col[] {
const colInfo = this._dataViz?.colsInfo;
- return this.selectedFields.map(field => {
- const fieldInfo = colInfo?.get(field);
-
- const col: Col = {
- title: field,
- type: fieldInfo?.type ?? TemplateFieldType.UNSET,
- desc: fieldInfo?.desc ?? '',
- sizes: fieldInfo?.sizes ?? [TemplateFieldSize.MEDIUM]
- };
-
- if (fieldInfo?.defaultContent !== undefined) {
- col.defaultContent = fieldInfo.defaultContent;
- }
+ return this.selectedFields
+ .map(field => {
+ const fieldInfo = colInfo?.get(field);
+
+ const col: Col = {
+ title: field,
+ type: fieldInfo?.type ?? TemplateFieldType.UNSET,
+ desc: fieldInfo?.desc ?? '',
+ sizes: fieldInfo?.sizes ?? [TemplateFieldSize.MEDIUM],
+ };
+
+ if (fieldInfo?.defaultContent !== undefined) {
+ col.defaultContent = fieldInfo.defaultContent;
+ }
- return col;
- }).concat(this._columns);
+ return col;
+ })
+ .concat(this._columns);
}
- @computed get canMakeDocs(){
+ @computed get canMakeDocs() {
return this._selectedTemplate !== undefined && this._layout !== undefined;
}
- get bounds(): {t: number, b: number, l: number, r: number} {
+ get bounds(): { t: number; b: number; l: number; r: number } {
const rect = this._ref?.getBoundingClientRect();
- const bounds = {t: rect?.top ?? 0, b: rect?.bottom ?? 0, l: rect?.left ?? 0, r: rect?.right ?? 0};
+ const bounds = { t: rect?.top ?? 0, b: rect?.bottom ?? 0, l: rect?.left ?? 0, r: rect?.right ?? 0 };
return bounds;
}
@@ -179,8 +181,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
clickEv.preventDefault();
func();
}, 'create docs')
- )
- }
+ );
+ };
@action
onPointerDown = (e: PointerEvent) => {
@@ -214,10 +216,21 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
componentDidMount() {
document.addEventListener('pointerdown', this.onPointerDown, true);
document.addEventListener('pointerup', this.onPointerUp);
- this._disposers.templates = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon));
- this._disposers.gpt = reaction(() => this._suggestedTemplates.slice(), (docs) => docs.map(this.getIcon));
+ this._disposers.templates = reaction(
+ () => this._templateDocs.slice(),
+ docs => docs.map(this.getIcon)
+ );
+ this._disposers.gpt = reaction(
+ () => this._suggestedTemplates.slice(),
+ docs => docs.map(this.getIcon)
+ );
//this._disposers.columns = reaction(() => this._dataViz?.layoutDoc._dataViz_axes, () => {this.generateTemplates('')})
- this._disposers.lightbox = reaction(() => LightboxView.LightboxDoc(), doc => { doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu()});
+ this._disposers.lightbox = reaction(
+ () => LightboxView.LightboxDoc(),
+ doc => {
+ doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu();
+ }
+ );
//this._disposers.fields = reaction(() => this._dataViz?.axes, cols => this._selectedCols = cols?.map(col => { return {title: col, type: '', desc: ''}}))
}
@@ -227,12 +240,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
document.removeEventListener('pointerup', this.onPointerUp);
}
- updateIcons = (docs: Doc[]) => { docs.map(this.getIcon) }
+ updateIcons = (docs: Doc[]) => {
+ docs.map(this.getIcon);
+ };
@action
updateSelectedCols = (cols: string[]) => {
- this._selectedCols
- }
+ this._selectedCols;
+ };
@action
toggleDisplay = (x: number, y: number) => {
@@ -246,10 +261,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
};
@action
- closeMenu = () => { this._shouldDisplay = false };
+ closeMenu = () => {
+ this._shouldDisplay = false;
+ };
@action
- openMenu = () => {
+ openMenu = () => {
const allTemplates = this._templateDocs.concat(this._suggestedTemplates);
this._shouldDisplay = true;
this.updateIcons(allTemplates);
@@ -285,7 +302,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
await new Promise<any>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
}); // prettier-ignore
return true;
- }
+ };
@action
onDrag = (e: any): boolean => {
@@ -294,12 +311,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this._initDimensions.x = this._pageX;
this._initDimensions.y = this._pageY;
return true;
- }
+ };
getResizeVals = (thisPt: { x: number; y: number }, dragHdl: string) => {
const [w, h] = [this._initDimensions.width, this._initDimensions.height];
const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y];
- let vals: {scale: {x: number, y: number}, refPt: [number, number], transl: {x: number, y: number}};
+ let vals: { scale: { x: number; y: number }; refPt: [number, number]; transl: { x: number; y: number } };
switch (dragHdl) {
case 'topLeft': vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: moveY } }; break;
case 'topRight': vals = { scale: { x: 1 + moveX / w, y: 1 -moveY / h }, refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: moveY } }; break;
@@ -314,11 +331,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
return vals;
};
- resizeView = (refPt: number[], scale: { x: number; y: number }, translation: {x: number, y: number}) => {
- const refCent = [refPt[0], refPt[1]] // fixed reference point for resize (ie, a point that doesn't move)
+ resizeView = (refPt: number[], scale: { x: number; y: number }, translation: { x: number; y: number }) => {
+ const refCent = [refPt[0], refPt[1]]; // fixed reference point for resize (ie, a point that doesn't move)
if (this._initDimensions.x === undefined) this._initDimensions.x = this._pageX;
if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY;
- const {height, width, x, y} = this._initDimensions;
+ const { height, width, x, y } = this._initDimensions;
this._menuDimensions.width = Math.max(300, scale.x * width);
this._menuDimensions.height = Math.max(200, scale.y * height);
@@ -330,10 +347,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const docView = DocumentView.getDocumentView(doc);
if (docView) {
docView.ComponentView?.updateIcon?.();
- return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500));;
+ return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500));
}
return undefined;
- };
+ }
@action updateSelectedTemplate = (template: Doc) => {
if (this._selectedTemplate === template) {
@@ -353,10 +370,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
};
isSelectedLayout = (layout: DataVizTemplateLayout) => {
- return this._layout.xMargin === layout.layout.xMargin
- && this._layout.yMargin === layout.layout.yMargin
- && this._layout.type === layout.layout.type
- && this._layout.columns === layout.columns;
+ return this._layout.xMargin === layout.layout.xMargin && this._layout.yMargin === layout.layout.yMargin && this._layout.type === layout.layout.type && this._layout.columns === layout.columns;
};
@action
@@ -365,7 +379,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const origCount = this._callCount;
let prompt: string = `(#${origCount}) Please generate for the fields:`;
- this.selectedFields?.forEach(field => prompt += ` ${field},`)
+ this.selectedFields?.forEach(field => (prompt += ` ${field},`));
prompt += ` (-----NOT A FIELD-----) Additional prompt: ${inputText}`;
this._GPTLoading = true;
@@ -375,37 +389,43 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
if (res && this._callCount === origCount) {
this._suggestedTemplates = [];
- const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res);
+ const templates: { template_type: string; fieldVals: { title: string; tlx: string; tly: string; brx: string; bry: string }[] }[] = JSON.parse(res);
this.createGeneratedTemplates(templates, 500, 500);
}
} catch (err) {
console.error(err);
- }
+ }
};
@action
- createGeneratedTemplates = (layouts: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[], tempWidth: number, tempHeight: number) => {
+ createGeneratedTemplates = (layouts: { template_type: string; fieldVals: { title: string; tlx: string; tly: string; brx: string; bry: string }[] }[], tempWidth: number, tempHeight: number) => {
const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
const GPTTemplates: Doc[] = [];
layouts.forEach(layout => {
const fields: Doc[] = layout.fieldVals.map(field => {
- const left: number = Number(field.tlx) * tempWidth / 2; const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore
- const right: number = Number(field.brx) * tempWidth / 2; const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore
- const height = bottom - top;
- const width = right - left;
- const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/\$\$/g, ''), x: left, y: top });
+ const left: number = (Number(field.tlx) * tempWidth) / 2;
+ const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore
+ const right: number = (Number(field.brx) * tempWidth) / 2;
+ const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore
+ const height = bottom - top;
+ const width = right - left;
+ const doc = !field.title.includes('$$')
+ ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height / 2}` })
+ : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/\$\$/g, ''), x: left, y: top });
return doc;
});
const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400000, y: 400000 });
mainCollection.addDocument(template);
-
+
GPTTemplates.push(template);
});
- setTimeout(() => {this.setGSuggestedTemplates(GPTTemplates); /*GPTTemplates.forEach(template => mainCollection.removeDocument(template))*/}, 100);
+ setTimeout(() => {
+ this.setGSuggestedTemplates(GPTTemplates); /*GPTTemplates.forEach(template => mainCollection.removeDocument(template))*/
+ }, 100);
this.forceUpdate();
};
@@ -421,9 +441,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this._templateDocs.splice(this._templateDocs.indexOf(doc), 1);
};
-
-
- testTemplate = async() => {
+ testTemplate = async () => {
// const temp = TemplateLayouts.FourField001;
// const title: Doc = FieldFuncs.TextField({tl: temp.fields[0].tl, br: temp.fields[0].br}, temp.height, temp.width, 'title', 'Title', {backgroundColor: 'transparent'});
// const image: Doc = FieldFuncs.ImageField({tl: temp.fields[1].tl, br: temp.fields[1].br}, temp.height, temp.width, 'title', '', {borderColor: '#159fe4', borderWidth: '10', cornerRounding: 10, rotation: 40});
@@ -453,7 +471,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
try {
const res = await gptImageCall('Image of panda eating a cookie');
- if (res){
+ if (res) {
const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
console.log(result);
@@ -461,15 +479,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
} catch (e) {
console.log(e);
}
-
};
@action addField = () => {
- const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.UNSET, desc: '', sizes: []}])
+ const newFields: Col[] = this._columns.concat([{ title: '', type: TemplateFieldType.UNSET, desc: '', sizes: [] }]);
this._columns = newFields;
};
- @action removeField = (field: {title: string, type: string, desc: string}) => {
+ @action removeField = (field: { title: string; type: string; desc: string }) => {
if (this._dataViz?.axes.includes(field.title)) {
this._dataViz.selectAxes(this._dataViz.axes.filter(col => col !== field.title));
} else {
@@ -483,11 +500,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
}
if (this._columns.length === 1) {
- this._columns = []
+ this._columns = [];
} else {
this._columns.splice(this._columns.indexOf(toRemove[0]), 1);
}
- }
+ }
};
@action setColTitle = (column: Col, title: string) => {
@@ -530,13 +547,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this.forceUpdate();
};
- generateGPTImage = async(prompt: string): Promise<string | undefined> => {
- console.log(prompt)
+ generateGPTImage = async (prompt: string): Promise<string | undefined> => {
+ console.log(prompt);
try {
const res = await gptImageCall(prompt);
- if (res){
+ if (res) {
const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
const source = ClientUtils.prepend(result[0].accessPaths.agnostic.client);
return source;
@@ -544,12 +561,16 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
} catch (e) {
console.log(e);
}
- }
+ };
matchesForTemplate = (template: TemplateDocInfos, cols: Col[]): number[][] => {
- const colMatchesField = (col: Col, field : Field) => { return field.sizes?.some(size => col.sizes?.includes(size)) && field.types?.includes(col.type) };
+ const colMatchesField = (col: Col, field: Field) => {
+ return field.sizes?.some(size => col.sizes?.includes(size)) && field.types?.includes(col.type);
+ };
- const matches: number[][] = Array(template.fields.length).fill([]).map(() => []);
+ const matches: number[][] = Array(template.fields.length)
+ .fill([])
+ .map(() => []);
template.fields.forEach((field, i) => {
cols.forEach((col, v) => {
@@ -576,8 +597,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
}
}
return false;
- }
-
+ };
+
for (let v = 0; v < fieldsCt; ++v) {
used.fill(false);
augmentingPath(v);
@@ -592,7 +613,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
return count;
};
-
findValidTemplates = (cols: Col[], templates: TemplateDocInfos[]) => {
let validTemplates: any[] = [];
templates.forEach(template => {
@@ -602,7 +622,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
if (this.maxMatches(numFields, matches) === numFields) {
validTemplates.push(template.title);
}
- })
+ });
validTemplates = validTemplates.map(title => TemplateLayouts.getTemplateByTitle(title));
@@ -613,12 +633,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
// if (field.subfields) {
// const doc = FieldFuncs.FreeformField({
- // tl: field.tl,
- // br: field.br },
- // template.height,
- // template.width,
- // column.title,
- // '',
+ // tl: field.tl,
+ // br: field.br },
+ // template.height,
+ // template.width,
+ // column.title,
+ // '',
// field.opts
// );
@@ -634,10 +654,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
/**
* Populates a preset template framework with content from a datavizbox or any AI-generated content.
* @param template the preloaded template framework being filled in
- * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
+ * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
* @returns a doc containing the fully rendered template
*/
- fillPresetTemplate = async(template: TemplateDocInfos, assignments: {[field: string]: Col}): Promise<Doc> => {
+ fillPresetTemplate = async (template: TemplateDocInfos, assignments: { [field: string]: Col }): Promise<Doc> => {
const wordLimit = (size: TemplateFieldSize) => {
switch (size) {
case TemplateFieldSize.TINY:
@@ -650,44 +670,43 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
return 50;
case TemplateFieldSize.HUGE:
return 100;
- default:
+ default:
return 10;
}
- }
+ };
- const renderTextCalls = async(): Promise<Doc[]> => {
+ const renderTextCalls = async (): Promise<Doc[]> => {
const rendered: Doc[] = [];
if (GPTTextCalls.length) {
-
try {
const prompt = fieldContent + GPTTextAssignment;
-
+
const res = await gptAPICall(prompt, GPTCallType.FILL);
-
- if (res){
-
- const assignments: {[title: string]: {number: string, content: string}} = JSON.parse(res);
+
+ if (res) {
+ const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
//console.log('assignments', GPTAssignments, 'assignment string', GPTAssignmentString, 'field content', fieldContent, 'response', res, 'assignments', assignments);
Object.entries(assignments).forEach(([title, info]) => {
const field: Field = template.fields[Number(info.number)];
const col = this.getColByTitle(title);
-
- const doc = FieldUtils.TextField({
- tl: field.tl,
- br: field.br },
- template.height,
- template.width,
- col.title,
- info.content ?? '',
+
+ const doc = FieldUtils.TextField(
+ {
+ tl: field.tl,
+ br: field.br,
+ },
+ template.height,
+ template.width,
+ col.title,
+ info.content ?? '',
field.opts
);
-
+
rendered.push(doc);
});
-
}
- } catch(err) {
+ } catch (err) {
console.log(err);
}
}
@@ -695,23 +714,25 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
return rendered;
};
- const createGeneratedImage = async(fieldNum: string, col: Col, prompt: string) => {
+ const createGeneratedImage = async (fieldNum: string, col: Col, prompt: string) => {
const url = await this.generateGPTImage(prompt);
const field: Field = template.fields[Number(fieldNum)];
- const doc = FieldUtils.ImageField({
- tl: field.tl,
- br: field.br },
- template.height,
- template.width,
- col.title,
- url ?? '',
+ const doc = FieldUtils.ImageField(
+ {
+ tl: field.tl,
+ br: field.br,
+ },
+ template.height,
+ template.width,
+ col.title,
+ url ?? '',
field.opts
);
return doc;
- }
+ };
- const renderImageCalls = async(): Promise<Doc[]> => {
+ const renderImageCalls = async (): Promise<Doc[]> => {
const rendered: Doc[] = [];
const calls = GPTIMGCalls;
@@ -719,24 +740,28 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
try {
const renderedImages: Doc[] = await Promise.all(
calls.map(async ([fieldNum, col]) => {
- const sysPrompt = 'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' + fieldContent + ' **** The user prompt is: ' + col.desc;
-
+ const sysPrompt =
+ 'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' +
+ fieldContent +
+ ' **** The user prompt is: ' +
+ col.desc;
+
const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
console.log(sysPrompt, prompt);
-
+
return createGeneratedImage(fieldNum, col, prompt);
})
);
-
+
const renderedTemplates: Doc[] = await Promise.all(renderedImages);
renderedTemplates.forEach(doc => rendered.push(doc));
- } catch (e){
+ } catch (e) {
console.log(e);
}
}
return rendered;
- }
+ };
const fields: Doc[] = [];
@@ -748,9 +773,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const stringifyGPTInfo = (calls: [string, Col][]): string => {
let string: string = '*** COLUMN INFO:';
calls.forEach(([fieldNum, col]) => {
- string += `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`
+ string += `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`;
});
- return string += ' ***';
+ return (string += ' ***');
};
const GPTTextAssignment = stringifyGPTInfo(GPTTextCalls);
@@ -761,45 +786,49 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const field: Field = template.fields[Number(f)];
const col = strCol[1];
- const doc = (col.type === TemplateFieldType.VISUAL ? FieldUtils.ImageField : FieldUtils.TextField)({
- tl: field.tl,
- br: field.br },
- template.height,
- template.width,
- col.title,
- col.defaultContent ?? '',
+ const doc = (col.type === TemplateFieldType.VISUAL ? FieldUtils.ImageField : FieldUtils.TextField)(
+ {
+ tl: field.tl,
+ br: field.br,
+ },
+ template.height,
+ template.width,
+ col.title,
+ col.defaultContent ?? '',
field.opts
);
- fieldContent += `--- Field #${f} (title: ${col.title}): ${col.defaultContent ?? ''} ---`
+ fieldContent += `--- Field #${f} (title: ${col.title}): ${col.defaultContent ?? ''} ---`;
fields.push(doc);
});
template.decorations.forEach(dec => {
- const doc = FieldUtils.FreeformField({
- tl: dec.tl,
- br: dec.br },
- template.height,
- template.width,
- '',
- '',
- dec.opts,
+ const doc = FieldUtils.FreeformField(
+ {
+ tl: dec.tl,
+ br: dec.br,
+ },
+ template.height,
+ template.width,
+ '',
+ '',
+ dec.opts
);
fields.push(doc);
});
const createMainDoc = (): Doc => {
- const main = Docs.Create.FreeformDocument(fields, {
- _height: template.height,
- _width: template.width,
- title: template.title,
+ const main = Docs.Create.FreeformDocument(fields, {
+ _height: template.height,
+ _width: template.width,
+ title: template.title,
backgroundColor: template.opts.backgroundColor,
- _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px',
+ _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px',
borderWidth: template.opts.borderWidth,
borderColor: template.opts.borderColor,
- x: 40000,
+ x: 40000,
y: 40000,
});
@@ -807,40 +836,46 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
mainCollection.addDocument(main);
return main;
- }
+ };
const textCalls = await renderTextCalls();
const imageCalls = await renderImageCalls();
- textCalls.forEach(doc => {fields.push(doc)});
- imageCalls.forEach(doc => {fields.push(doc)});
+ textCalls.forEach(doc => {
+ fields.push(doc);
+ });
+ imageCalls.forEach(doc => {
+ fields.push(doc);
+ });
return createMainDoc();
- }
+ };
compileFieldDescriptions = (templates: TemplateDocInfos[]): string => {
let descriptions: string = '';
templates.forEach(template => {
- descriptions += `---------- NEW TEMPLATE TO INCLUDE: Description of template ${template.title}'s fields: `
+ descriptions += `---------- NEW TEMPLATE TO INCLUDE: Description of template ${template.title}'s fields: `;
template.fields.forEach((field, index) => {
- descriptions += `{Field #${index}: ${field.description}} `
+ descriptions += `{Field #${index}: ${field.description}} `;
});
});
return descriptions;
};
- compileColDescriptions = (cols: Col[]): string => {
+ compileColDescriptions = (cols: Col[]): string => {
let descriptions: string = ' ------------- COL DESCRIPTIONS START HERE:';
- cols.forEach(col => descriptions += `{title: ${col.title}, sizes: ${String(col.sizes)}, type: ${col.type}, descreiption: ${col.desc}} `);
+ cols.forEach(col => (descriptions += `{title: ${col.title}, sizes: ${String(col.sizes)}, type: ${col.type}, descreiption: ${col.desc}} `));
return descriptions;
};
- getColByTitle = (title: string) => { return this.fieldsInfos.filter(col => col.title === title)[0]; };
+ getColByTitle = (title: string) => {
+ return this.fieldsInfos.filter(col => col.title === title)[0];
+ };
@action
- assignColsToFields = async(templates: TemplateDocInfos[], cols: Col[]): Promise<[TemplateDocInfos, {[field: number]: Col}][]> => {
+ assignColsToFields = async (templates: TemplateDocInfos[], cols: Col[]): Promise<[TemplateDocInfos, { [field: number]: Col }][]> => {
const fieldDescriptions: string = this.compileFieldDescriptions(templates);
const colDescriptions: string = this.compileColDescriptions(cols);
@@ -857,24 +892,26 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const res = await gptAPICall(prompt, GPTCallType.TEMPLATE);
if (res && this._callCount === origCount) {
-
- const assignments: {[templateTitle: string]: {[field: string]: string}} = JSON.parse(res);
- const brokenDownAssignments: [TemplateDocInfos, {[field: number]: Col}][] = [];
+ const assignments: { [templateTitle: string]: { [field: string]: string } } = JSON.parse(res);
+ const brokenDownAssignments: [TemplateDocInfos, { [field: number]: Col }][] = [];
Object.entries(assignments).forEach(([tempTitle, assignment]) => {
const template = TemplateLayouts.getTemplateByTitle(tempTitle);
if (!template) return;
- const toObj = Object.entries(assignment).reduce((a, [fieldNum, colTitle]) => {
- a[Number(fieldNum)] = this.getColByTitle(colTitle);
- return a;
- }, {} as { [field: number]: Col });
- brokenDownAssignments.push([template, toObj])
- })
+ const toObj = Object.entries(assignment).reduce(
+ (a, [fieldNum, colTitle]) => {
+ a[Number(fieldNum)] = this.getColByTitle(colTitle);
+ return a;
+ },
+ {} as { [field: number]: Col }
+ );
+ brokenDownAssignments.push([template, toObj]);
+ });
return brokenDownAssignments;
}
} catch (err) {
console.error(err);
- }
+ }
return [];
};
@@ -884,178 +921,200 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const cols = this.fieldsInfos;
const templates = this.findValidTemplates(cols, TemplateLayouts.allTemplates);
-
+
const assignments: [TemplateDocInfos, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
-
- const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) =>
- this.fillPresetTemplate(template, assignments)
- );
-
+
+ const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) => this.fillPresetTemplate(template, assignments));
+
const renderedTemplates: Doc[] = await Promise.all(renderedTemplatePromises);
-
- setTimeout(() => { this.setGSuggestedTemplates(renderedTemplates); this._GPTLoading = false });
+
+ setTimeout(() => {
+ this.setGSuggestedTemplates(renderedTemplates);
+ this._GPTLoading = false;
+ });
};
- @action setExpandedView = (info: {icon: ImageField, doc: Doc} | undefined) => {
+ @action setExpandedView = (info: { icon: ImageField; doc: Doc } | undefined) => {
this._expandedPreview = info;
- }
+ };
- get templatesPreviewContents(){
+ get templatesPreviewContents() {
const renderedTemplates: Doc[] = [];
- const GPTOptions =
- <div></div>
+ const GPTOptions = <div></div>;
- //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
+ //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
return (
<div className={`docCreatorMenu-templates-view`}>
- {this._expandedPreview ?
- <div className='docCreatorMenu-expanded-template-preview'>
- <img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
- <div className='right-buttons-panel'>
- <button className='docCreatorMenu-menu-button section-reveal-options top-right' onPointerDown={e => this.setUpButtonClick(e, () => this.setExpandedView(undefined))}>
- <FontAwesomeIcon icon='minimize'/>
- </button>
- <button className='docCreatorMenu-menu-button section-reveal-options top-right-lower' onPointerDown={e => this.setUpButtonClick(e, () => this._expandedPreview && this._templateDocs.push(this._expandedPreview.doc))}>
- <FontAwesomeIcon icon='plus' color='white'/>
- </button>
- </div>
- </div>
- :
- <div>
- <div className='docCreatorMenu-section' style={{height: this._GPTOpt ? 200 : 200}}>
- <div className='docCreatorMenu-section-topbar'>
- <div className='docCreatorMenu-section-title'>Suggested Templates</div>
- <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._menuContent = 'dashboard'))}>
- <FontAwesomeIcon icon='gear'/>
+ {this._expandedPreview ? (
+ <div className="docCreatorMenu-expanded-template-preview">
+ <img className="docCreatorMenu-preview-image expanded" src={this._expandedPreview.icon!.url.href.replace('.png', '_o.png')} />
+ <div className="right-buttons-panel">
+ <button className="docCreatorMenu-menu-button section-reveal-options top-right" onPointerDown={e => this.setUpButtonClick(e, () => this.setExpandedView(undefined))}>
+ <FontAwesomeIcon icon="minimize" />
+ </button>
+ <button className="docCreatorMenu-menu-button section-reveal-options top-right-lower" onPointerDown={e => this.setUpButtonClick(e, () => this._expandedPreview && this._templateDocs.push(this._expandedPreview.doc))}>
+ <FontAwesomeIcon icon="plus" color="white" />
</button>
</div>
- <div className='docCreatorMenu-templates-preview-window' style={{justifyContent: this._GPTLoading || this._menuDimensions.width > 400 ? 'center' : ''}}>
- {this._GPTLoading ? (
- <div className="loading-spinner">
- <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
- </div>
- ) : (
- this._suggestedTemplates?.map(doc =>
- ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info =>
- <div
- className='docCreatorMenu-preview-window'
- style={{
- border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
- boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : ''
- }}
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
- <button className='option-button left' onPointerDown={e => this.setUpButtonClick(e, () => {this.setExpandedView(info)})}>
- <FontAwesomeIcon icon='magnifying-glass' color='white'/>
- </button>
- <button className='option-button right' onPointerDown={e => this.setUpButtonClick(e, () => this._templateDocs.push(info.doc))}>
- <FontAwesomeIcon icon='plus' color='white'/>
- </button>
- <img className='docCreatorMenu-preview-image' src={info.icon!.url.href.replace(".png", "_o.png")} />
- </div>
- ))}
- </div>
- <div className='docCreatorMenu-GPT-options'>
- <div className='docCreatorMenu-GPT-options-container'>
- <button className='docCreatorMenu-menu-button' onPointerDown={e => this.setUpButtonClick(e, () => this.generatePresetTemplates())}>
- <FontAwesomeIcon icon='arrows-rotate'/>
+ </div>
+ ) : (
+ <div>
+ <div className="docCreatorMenu-section" style={{ height: this._GPTOpt ? 200 : 200 }}>
+ <div className="docCreatorMenu-section-topbar">
+ <div className="docCreatorMenu-section-title">Suggested Templates</div>
+ <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'dashboard')))}>
+ <FontAwesomeIcon icon="gear" />
</button>
</div>
- {this._GPTOpt ? GPTOptions : null }
- </div>
- </div>
- <hr className='docCreatorMenu-option-divider full no-margin'/>
- <div className='docCreatorMenu-section'>
- <div className='docCreatorMenu-section-topbar'>
- <div className='docCreatorMenu-section-title'>Your Templates</div>
- <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, () => this._GPTOpt = !this._GPTOpt)}>
- <FontAwesomeIcon icon='gear'/>
- </button>
- </div>
- <div className='docCreatorMenu-templates-preview-window' style={{justifyContent: this._menuDimensions.width > 400 ? 'center' : ''}}>
- <div className='docCreatorMenu-preview-window empty' onPointerDown={e => this.testTemplate()}>
- <FontAwesomeIcon icon='plus' color='rgb(160, 160, 160)'/>
+ <div className="docCreatorMenu-templates-preview-window" style={{ justifyContent: this._GPTLoading || this._menuDimensions.width > 400 ? 'center' : '' }}>
+ {this._GPTLoading ? (
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ </div>
+ ) : (
+ this._suggestedTemplates
+ ?.map(doc => ({ icon: ImageCast(doc.icon), doc }))
+ .filter(info => info.icon && info.doc)
+ .map(info => (
+ <div
+ className="docCreatorMenu-preview-window"
+ style={{
+ border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+ boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+ }}
+ onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
+ <button
+ className="option-button left"
+ onPointerDown={e =>
+ this.setUpButtonClick(e, () => {
+ this.setExpandedView(info);
+ })
+ }>
+ <FontAwesomeIcon icon="magnifying-glass" color="white" />
+ </button>
+ <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this._templateDocs.push(info.doc))}>
+ <FontAwesomeIcon icon="plus" color="white" />
+ </button>
+ <img className="docCreatorMenu-preview-image" src={info.icon!.url.href.replace('.png', '_o.png')} />
+ </div>
+ ))
+ )}
+ </div>
+ <div className="docCreatorMenu-GPT-options">
+ <div className="docCreatorMenu-GPT-options-container">
+ <button className="docCreatorMenu-menu-button" onPointerDown={e => this.setUpButtonClick(e, () => this.generatePresetTemplates())}>
+ <FontAwesomeIcon icon="arrows-rotate" />
+ </button>
+ </div>
+ {this._GPTOpt ? GPTOptions : null}
+ </div>
</div>
- {this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => {
- if (renderedTemplates.includes(info.doc)) return undefined;
- renderedTemplates.push(info.doc);
- return (<div
- className='docCreatorMenu-preview-window'
- style={{
- border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
- boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : ''
- }}
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
- <button className='option-button left' onPointerDown={e => this.setUpButtonClick(e, () => {this.editTemplate(info.doc)})}>
- <FontAwesomeIcon icon='pencil' color='black'/>
- </button>
- <button className='option-button right' onPointerDown={e => this.setUpButtonClick(e, () => {this.removeTemplate(info.doc)})}>
- <FontAwesomeIcon icon='trash' color='black'/>
+ <hr className="docCreatorMenu-option-divider full no-margin" />
+ <div className="docCreatorMenu-section">
+ <div className="docCreatorMenu-section-topbar">
+ <div className="docCreatorMenu-section-title">Your Templates</div>
+ <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => (this._GPTOpt = !this._GPTOpt))}>
+ <FontAwesomeIcon icon="gear" />
</button>
- <img className='docCreatorMenu-preview-image' src={info.icon!.url.href.replace(".png", "_o.png")} />
</div>
- )})}
+ <div className="docCreatorMenu-templates-preview-window" style={{ justifyContent: this._menuDimensions.width > 400 ? 'center' : '' }}>
+ <div className="docCreatorMenu-preview-window empty" onPointerDown={e => this.testTemplate()}>
+ <FontAwesomeIcon icon="plus" color="rgb(160, 160, 160)" />
+ </div>
+ {this._templateDocs
+ .map(doc => ({ icon: ImageCast(doc.icon), doc }))
+ .filter(info => info.icon && info.doc)
+ .map(info => {
+ if (renderedTemplates.includes(info.doc)) return undefined;
+ renderedTemplates.push(info.doc);
+ return (
+ <div
+ className="docCreatorMenu-preview-window"
+ style={{
+ border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+ boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+ }}
+ onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
+ <button
+ className="option-button left"
+ onPointerDown={e =>
+ this.setUpButtonClick(e, () => {
+ this.editTemplate(info.doc);
+ })
+ }>
+ <FontAwesomeIcon icon="pencil" color="black" />
+ </button>
+ <button
+ className="option-button right"
+ onPointerDown={e =>
+ this.setUpButtonClick(e, () => {
+ this.removeTemplate(info.doc);
+ })
+ }>
+ <FontAwesomeIcon icon="trash" color="black" />
+ </button>
+ <img className="docCreatorMenu-preview-image" src={info.icon!.url.href.replace('.png', '_o.png')} />
+ </div>
+ );
+ })}
+ </div>
</div>
</div>
- </div>
- }
+ )}
</div>
);
}
- get savedLayoutsPreviewContents(){
+ get savedLayoutsPreviewContents() {
return (
- <div className='docCreatorMenu-preview-container'>
- {this._savedLayouts.map((layout, index) =>
- <div
- className='docCreatorMenu-preview-window'
- style={{
- border: this.isSelectedLayout(layout) ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
- boxShadow: this.isSelectedLayout(layout) ? `0 0 15px rgba(68, 118, 247, .8)` : ''
- }}
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))}
- >
- {this.layoutPreviewContents(87, layout, true, index)}
- </div>
- )}
+ <div className="docCreatorMenu-preview-container">
+ {this._savedLayouts.map((layout, index) => (
+ <div
+ className="docCreatorMenu-preview-window"
+ style={{
+ border: this.isSelectedLayout(layout) ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+ boxShadow: this.isSelectedLayout(layout) ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+ }}
+ onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))}>
+ {this.layoutPreviewContents(87, layout, true, index)}
+ </div>
+ ))}
</div>
);
}
- @action updateXMargin = (input: string) => { this._layout.xMargin = Number(input) };
- @action updateYMargin = (input: string) => { this._layout.yMargin = Number(input) };
- @action updateColumns = (input: string) => { this._layout.columns = Number(input) };
+ @action updateXMargin = (input: string) => {
+ this._layout.xMargin = Number(input);
+ };
+ @action updateYMargin = (input: string) => {
+ this._layout.yMargin = Number(input);
+ };
+ @action updateColumns = (input: string) => {
+ this._layout.columns = Number(input);
+ };
get layoutConfigOptions() {
const optionInput = (icon: string, func: Function, def?: number, key?: string, noMargin?: boolean) => {
return (
- <div className='docCreatorMenu-option-container small no-margin' key={key} style={{marginTop: noMargin ? '0px' : ''}}
- >
- <div className='docCreatorMenu-option-title config layout-config'>
- <FontAwesomeIcon icon={icon as any}/>
+ <div className="docCreatorMenu-option-container small no-margin" key={key} style={{ marginTop: noMargin ? '0px' : '' }}>
+ <div className="docCreatorMenu-option-title config layout-config">
+ <FontAwesomeIcon icon={icon as any} />
</div>
- <input defaultValue={def} onInput={(e) => func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/>
+ <input defaultValue={def} onInput={e => func(e.currentTarget.value)} className="docCreatorMenu-input config layout-config" />
</div>
);
- }
+ };
switch (this._layout.type) {
case LayoutType.Row:
- return (
- <div className='docCreatorMenu-configuration-bar'>
- {optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '0')}
- </div>
- );
+ return <div className="docCreatorMenu-configuration-bar">{optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '0')}</div>;
case LayoutType.Column:
- return (
- <div className='docCreatorMenu-configuration-bar'>
- {optionInput('arrows-up-down', this.updateYMargin, this._layout.yMargin, '1')}
- </div>
- );
+ return <div className="docCreatorMenu-configuration-bar">{optionInput('arrows-up-down', this.updateYMargin, this._layout.yMargin, '1')}</div>;
case LayoutType.Grid:
return (
- <div className='docCreatorMenu-configuration-bar'>
+ <div className="docCreatorMenu-configuration-bar">
{optionInput('arrows-up-down', this.updateYMargin, this._layout.xMargin, '2')}
{optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '3')}
{optionInput('table-columns', this.updateColumns, this._layout.columns, '4', true)}
@@ -1072,9 +1131,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
// return Docs.Create.FreeformDocument([], { _height: 200, _width: 200, title: 'title'});
// }
- screenToLocalTransform = () =>
- this._props
- .ScreenToLocalTransform();
+ screenToLocalTransform = () => this._props.ScreenToLocalTransform();
layoutPreviewContents = (outerSpan: number, altLayout?: DataVizTemplateLayout, small: boolean = false, id?: number) => {
const doc: Doc | undefined = altLayout ? altLayout.template : this._selectedTemplate;
@@ -1084,10 +1141,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const docWidth: number = Number(doc._width);
const docHeight: number = Number(doc._height);
- const horizontalSpan: number = (docWidth + layout.xMargin) * (altLayout ? altLayout.columns : this.columnsCount) - layout.xMargin;;
+ const horizontalSpan: number = (docWidth + layout.xMargin) * (altLayout ? altLayout.columns : this.columnsCount) - layout.xMargin;
const verticalSpan: number = (docHeight + layout.yMargin) * (altLayout ? altLayout.rows : this.rowsCount) - layout.yMargin;
const largerSpan: number = horizontalSpan > verticalSpan ? horizontalSpan : verticalSpan;
- const scaledDown = (input: number) => {return input / (largerSpan / outerSpan * this._layoutPreviewScale)}
+ const scaledDown = (input: number) => {
+ return input / ((largerSpan / outerSpan) * this._layoutPreviewScale);
+ };
const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3));
return (
@@ -1114,220 +1173,275 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
// {null}
// </CollectionFreeFormView>
// </div>
- <div className='docCreatorMenu-layout-preview-window-wrapper' id={String(id) ?? undefined}>
- <div className='docCreatorMenu-zoom-button-container'>
- <button
- className='docCreatorMenu-zoom-button'
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= 1.25))}>
- <FontAwesomeIcon icon={'minus'}/>
+ <div className="docCreatorMenu-layout-preview-window-wrapper" id={String(id) ?? undefined}>
+ <div className="docCreatorMenu-zoom-button-container">
+ <button className="docCreatorMenu-zoom-button" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreviewScale *= 1.25)))}>
+ <FontAwesomeIcon icon={'minus'} />
</button>
- <button
- className='docCreatorMenu-zoom-button zoom-in'
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= .75))}>
- <FontAwesomeIcon icon={'plus'}/>
+ <button className="docCreatorMenu-zoom-button zoom-in" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreviewScale *= 0.75)))}>
+ <FontAwesomeIcon icon={'plus'} />
</button>
- {altLayout ? <button
- className='docCreatorMenu-zoom-button trash'
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._savedLayouts.splice(this._savedLayouts.indexOf(altLayout), 1)))}>
- <FontAwesomeIcon icon={'trash'}/>
- </button> : null}
+ {altLayout ? (
+ <button className="docCreatorMenu-zoom-button trash" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._savedLayouts.splice(this._savedLayouts.indexOf(altLayout), 1)))}>
+ <FontAwesomeIcon icon={'trash'} />
+ </button>
+ ) : null}
</div>
- {<div
- id={String(id) ?? undefined}
- className={`docCreatorMenu-layout-preview-window ${small ? 'small' : ''}`}
- style={{
- gridTemplateColumns: `repeat(${altLayout ? altLayout.columns : this.columnsCount}, ${scaledDown(docWidth)}px`,
- gridTemplateRows: `${scaledDown(docHeight)}px`,
- gridAutoRows: `${scaledDown(docHeight)}px`,
- rowGap: `${scaledDown(layout.yMargin)}px`,
- columnGap: `${scaledDown(layout.xMargin)}px`
- }}>
- {this._layout.type === LayoutType.Stacked ?
- <div
- className='docCreatorMenu-layout-preview-item'
- style={{
- width: scaledDown(docWidth),
- height: scaledDown(docHeight),
- fontSize: fontSize,
- }}
- >
- All
- </div> :
- this.docsToRender.map(num =>
- <div
- onMouseEnter={() => this._dataViz?.setSpecialHighlightedRow(num)}
- onMouseLeave={() => this._dataViz?.setSpecialHighlightedRow(undefined)}
- className='docCreatorMenu-layout-preview-item'
+ {
+ <div
+ id={String(id) ?? undefined}
+ className={`docCreatorMenu-layout-preview-window ${small ? 'small' : ''}`}
style={{
- width: scaledDown(docWidth),
- height: scaledDown(docHeight),
- fontSize: fontSize,
- }}
- >
- {num}
- </div>
- )}
-
- </div>}
+ gridTemplateColumns: `repeat(${altLayout ? altLayout.columns : this.columnsCount}, ${scaledDown(docWidth)}px`,
+ gridTemplateRows: `${scaledDown(docHeight)}px`,
+ gridAutoRows: `${scaledDown(docHeight)}px`,
+ rowGap: `${scaledDown(layout.yMargin)}px`,
+ columnGap: `${scaledDown(layout.xMargin)}px`,
+ }}>
+ {this._layout.type === LayoutType.Stacked ? (
+ <div
+ className="docCreatorMenu-layout-preview-item"
+ style={{
+ width: scaledDown(docWidth),
+ height: scaledDown(docHeight),
+ fontSize: fontSize,
+ }}>
+ All
+ </div>
+ ) : (
+ this.docsToRender.map(num => (
+ <div
+ onMouseEnter={() => this._dataViz?.setSpecialHighlightedRow(num)}
+ onMouseLeave={() => this._dataViz?.setSpecialHighlightedRow(undefined)}
+ className="docCreatorMenu-layout-preview-item"
+ style={{
+ width: scaledDown(docWidth),
+ height: scaledDown(docHeight),
+ fontSize: fontSize,
+ }}>
+ {num}
+ </div>
+ ))
+ )}
+ </div>
+ }
</div>
);
- }
-
- get optionsMenuContents(){
- const layoutEquals = (layout: DataVizTemplateLayout) => {
+ };
- } //TODO: ADD LATER
+ get optionsMenuContents() {
+ const layoutEquals = (layout: DataVizTemplateLayout) => {}; //TODO: ADD LATER
const layoutOption = (option: LayoutType, optStyle?: {}, specialFunc?: Function) => {
return (
- <div
- className="docCreatorMenu-dropdown-option"
+ <div
+ className="docCreatorMenu-dropdown-option"
style={optStyle}
- onPointerDown={e => this.setUpButtonClick(e, () => {specialFunc?.(); runInAction(() => this._layout.type = option)})}>
+ onPointerDown={e =>
+ this.setUpButtonClick(e, () => {
+ specialFunc?.();
+ runInAction(() => (this._layout.type = option));
+ })
+ }>
{option}
</div>
);
- }
+ };
const selectionBox = (width: number, height: number, icon: string, specClass?: string, options?: JSX.Element[], manual?: boolean): JSX.Element => {
- return (<div className='docCreatorMenu-option-container'>
- <div className={`docCreatorMenu-option-title config ${specClass}`} style={{width: width * .4, height: height}}>
- <FontAwesomeIcon icon={icon as any}/>
+ return (
+ <div className="docCreatorMenu-option-container">
+ <div className={`docCreatorMenu-option-title config ${specClass}`} style={{ width: width * 0.4, height: height }}>
+ <FontAwesomeIcon icon={icon as any} />
+ </div>
+ {manual ? (
+ <input className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }} />
+ ) : (
+ <select className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }}>
+ {options}
+ </select>
+ )}
</div>
- {manual ? <input className={`docCreatorMenu-input config ${specClass}`} style={{width: width * .6, height: height}}/> :
- <select className={`docCreatorMenu-input config ${specClass}`} style={{width: width * .6, height: height}}>
- {options}
- </select>
- }
- </div>);
- }
+ );
+ };
const repeatOptions = [0, 1, 2, 3, 4, 5];
return (
- <div className='docCreatorMenu-menu-container'>
- <div className='docCreatorMenu-option-container layout'>
- <div className='docCreatorMenu-dropdown-hoverable'>
+ <div className="docCreatorMenu-menu-container">
+ <div className="docCreatorMenu-option-container layout">
+ <div className="docCreatorMenu-dropdown-hoverable">
<div className="docCreatorMenu-option-title">{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}</div>
<div className="docCreatorMenu-dropdown-content">
{layoutOption(LayoutType.Stacked)}
- {layoutOption(LayoutType.Grid, undefined, () => {if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length))})}
+ {layoutOption(LayoutType.Grid, undefined, () => {
+ if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length));
+ })}
{layoutOption(LayoutType.Row)}
{layoutOption(LayoutType.Column)}
- {layoutOption(LayoutType.Custom, {borderBottom: `0px`})}
+ {layoutOption(LayoutType.Custom, { borderBottom: `0px` })}
</div>
</div>
- <button
- className='docCreatorMenu-menu-button preview-toggle'
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreview = !this._layoutPreview))}>
- <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'}/>
+ <button className="docCreatorMenu-menu-button preview-toggle" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreview = !this._layoutPreview)))}>
+ <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'} />
</button>
</div>
- {this._layout.type ? this.layoutConfigOptions: null}
- {this._layoutPreview ? this.layoutPreviewContents(this._menuDimensions.width * .75) : null}
- {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => <option onPointerDown={e => this._layout.repeat = num}>{`${num}x`}</option>))}
- <hr className='docCreatorMenu-option-divider'/>
- <div className='docCreatorMenu-general-options-container'>
+ {this._layout.type ? this.layoutConfigOptions : null}
+ {this._layoutPreview ? this.layoutPreviewContents(this._menuDimensions.width * 0.75) : null}
+ {selectionBox(
+ 60,
+ 20,
+ 'repeat',
+ undefined,
+ repeatOptions.map(num => <option onPointerDown={e => (this._layout.repeat = num)}>{`${num}x`}</option>)
+ )}
+ <hr className="docCreatorMenu-option-divider" />
+ <div className="docCreatorMenu-general-options-container">
<button
- className='docCreatorMenu-save-layout-button'
- onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction,
- undoable(clickEv => {
- clickEv.stopPropagation();
- if (!this._selectedTemplate) return;
- const layout: DataVizTemplateLayout = {template: this._selectedTemplate, layout: {type: this._layout.type, xMargin: this._layout.xMargin, yMargin:this._layout.yMargin, repeat: 0}, columns: this.columnsCount, rows: this.rowsCount, docsNumList: this.docsToRender};
- if (!this._savedLayouts.includes(layout)) { this._savedLayouts.push(layout) };
- }, 'make docs')
- )
- }>
- <FontAwesomeIcon icon='floppy-disk'/>
+ className="docCreatorMenu-save-layout-button"
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoable(clickEv => {
+ clickEv.stopPropagation();
+ if (!this._selectedTemplate) return;
+ const layout: DataVizTemplateLayout = {
+ template: this._selectedTemplate,
+ layout: { type: this._layout.type, xMargin: this._layout.xMargin, yMargin: this._layout.yMargin, repeat: 0 },
+ columns: this.columnsCount,
+ rows: this.rowsCount,
+ docsNumList: this.docsToRender,
+ };
+ if (!this._savedLayouts.includes(layout)) {
+ this._savedLayouts.push(layout);
+ }
+ }, 'make docs')
+ )
+ }>
+ <FontAwesomeIcon icon="floppy-disk" />
</button>
- <button
- className='docCreatorMenu-create-docs-button'
- style={{backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'solid 2px rgb(180, 180, 180)'}}
- onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction,
+ <button
+ className="docCreatorMenu-create-docs-button"
+ style={{ backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'solid 2px rgb(180, 180, 180)' }}
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
undoable(clickEv => {
clickEv.stopPropagation();
if (!this._selectedTemplate) return;
- const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate, layout: this._layout, referencePos: {x: this._pageX + 450, y: this._pageY}, columns: this.columnsCount};
+ const templateInfo: DataVizTemplateInfo = { doc: this._selectedTemplate, layout: this._layout, referencePos: { x: this._pageX + 450, y: this._pageY }, columns: this.columnsCount };
this._dataViz?.createDocsFromTemplate(templateInfo);
- }, 'make docs')
+ }, 'make docs')
)
}>
- <FontAwesomeIcon icon='plus'/>
+ <FontAwesomeIcon icon="plus" />
</button>
</div>
</div>
);
}
- get dashboardContents(){
+ get dashboardContents() {
const sizes: string[] = ['tiny', 'small', 'medium', 'large', 'huge'];
const fieldPanel = (field: Col) => {
return (
- <div className='field-panel'>
- <div className='top-bar'>
- <span className='field-title'>{`${field.title} Field`}</span>
- <button className='docCreatorMenu-menu-button section-reveal-options no-margin' onPointerDown={e => this.setUpButtonClick(e, this.addField)} style={{position: 'absolute', right: '0px'}}>
- <FontAwesomeIcon icon='minus'/>
+ <div className="field-panel">
+ <div className="top-bar">
+ <span className="field-title">{`${field.title} Field`}</span>
+ <button className="docCreatorMenu-menu-button section-reveal-options no-margin" onPointerDown={e => this.setUpButtonClick(e, this.addField)} style={{ position: 'absolute', right: '0px' }}>
+ <FontAwesomeIcon icon="minus" />
</button>
</div>
- <div className='opts-bar'>
- <div className='opt-box'>
- <div className='top-bar'> Title </div>
- <textarea className='content' style={{width: '100%', height: 'calc(100% - 20px)'}} defaultValue={field.title} placeholder={'Enter title'} onChange={(e) => this.setColTitle(field, e.target.value)}/>
+ <div className="opts-bar">
+ <div className="opt-box">
+ <div className="top-bar"> Title </div>
+ <textarea className="content" style={{ width: '100%', height: 'calc(100% - 20px)' }} defaultValue={field.title} placeholder={'Enter title'} onChange={e => this.setColTitle(field, e.target.value)} />
</div>
- <div className='opt-box'>
- <div className='top-bar'> Type </div>
- <div className='content'>
- <span className='type-display'>{field.type === TemplateFieldType.TEXT ? 'Text Field' : field.type === TemplateFieldType.VISUAL ? 'File Field' : ''}</span>
- <div className='bubbles'>
- <input className='bubble' type="radio" name="type" onClick={() => {this.setColType(field, TemplateFieldType.TEXT)}}/>
- <div className='text'>Text</div>
- <input className='bubble' type="radio" name="type" onClick={() => {this.setColType(field, TemplateFieldType.VISUAL)}}/>
- <div className='text'>File</div>
+ <div className="opt-box">
+ <div className="top-bar"> Type </div>
+ <div className="content">
+ <span className="type-display">{field.type === TemplateFieldType.TEXT ? 'Text Field' : field.type === TemplateFieldType.VISUAL ? 'File Field' : ''}</span>
+ <div className="bubbles">
+ <input
+ className="bubble"
+ type="radio"
+ name="type"
+ onClick={() => {
+ this.setColType(field, TemplateFieldType.TEXT);
+ }}
+ />
+ <div className="text">Text</div>
+ <input
+ className="bubble"
+ type="radio"
+ name="type"
+ onClick={() => {
+ this.setColType(field, TemplateFieldType.VISUAL);
+ }}
+ />
+ <div className="text">File</div>
</div>
</div>
</div>
</div>
- <div className='sizes-box'>
- <div className='top-bar'> Valid Sizes </div>
- <div className='content'>
- <div className='bubbles'>
- {sizes.map(size => <>
- <input className='bubble' type="checkbox" name="type" checked={field.sizes.includes(size as TemplateFieldSize)} onChange={(e) => {this.modifyColSizes(field, size as TemplateFieldSize, e.target.checked)}}/>
- <div className='text'>{size}</div>
- </>)}
+ <div className="sizes-box">
+ <div className="top-bar"> Valid Sizes </div>
+ <div className="content">
+ <div className="bubbles">
+ {sizes.map(size => (
+ <>
+ <input
+ className="bubble"
+ type="checkbox"
+ name="type"
+ checked={field.sizes.includes(size as TemplateFieldSize)}
+ onChange={e => {
+ this.modifyColSizes(field, size as TemplateFieldSize, e.target.checked);
+ }}
+ />
+ <div className="text">{size}</div>
+ </>
+ ))}
</div>
</div>
</div>
- <div className='desc-box'>
- <div className='top-bar'> Description </div>
- <textarea className='content' onChange={(e) => this.setColDesc(field, e.target.value)} defaultValue={field.desc === this._dataViz?.GPTSummary?.get(field.title)?.desc ? '' : field.desc } placeholder={this._dataViz?.GPTSummary?.get(field.title)?.desc ?? 'Add a description to help with template generation.'} />
+ <div className="desc-box">
+ <div className="top-bar"> Description </div>
+ <textarea
+ className="content"
+ onChange={e => this.setColDesc(field, e.target.value)}
+ defaultValue={field.desc === this._dataViz?.GPTSummary?.get(field.title)?.desc ? '' : field.desc}
+ placeholder={this._dataViz?.GPTSummary?.get(field.title)?.desc ?? 'Add a description to help with template generation.'}
+ />
</div>
</div>
- )
- }
+ );
+ };
return (
- <div className='docCreatorMenu-dashboard-view'>
- <div className='topbar'>
- <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, this.addField)}>
- <FontAwesomeIcon icon='plus'/>
- </button>
- <button className='docCreatorMenu-menu-button section-reveal-options float-right' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._menuContent = 'templates'))}>
- <FontAwesomeIcon icon='arrow-left'/>
- </button>
- </div>
- <div className='panels-container'>
- {this.fieldsInfos.map(field => fieldPanel(field))}
+ <div className="docCreatorMenu-dashboard-view">
+ <div className="topbar">
+ <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, this.addField)}>
+ <FontAwesomeIcon icon="plus" />
+ </button>
+ <button className="docCreatorMenu-menu-button section-reveal-options float-right" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'templates')))}>
+ <FontAwesomeIcon icon="arrow-left" />
+ </button>
+ </div>
+ <div className="panels-container">{this.fieldsInfos.map(field => fieldPanel(field))}</div>
</div>
- </div>
);
}
- get renderSelectedViewType(){
- switch (this._menuContent){
+ get renderSelectedViewType() {
+ switch (this._menuContent) {
case 'templates':
return this.templatesPreviewContents;
case 'options':
@@ -1341,7 +1455,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
}
}
- get resizePanes(){
+ get resizePanes() {
const ref = this._ref?.getBoundingClientRect();
const height: number = ref?.height ?? 0;
const width: number = ref?.width ?? 0;
@@ -1362,90 +1476,96 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const topButton = (icon: string, opt: string, func: Function, tag: string) => {
return (
<div className={`top-button-container ${tag} ${opt === this._menuContent ? 'selected' : ''}`}>
- <div
+ <div
className="top-button-content"
- onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => {func()}))}>
- <FontAwesomeIcon icon={icon as any}/>
+ onPointerDown={e =>
+ this.setUpButtonClick(e, () =>
+ runInAction(() => {
+ func();
+ })
+ )
+ }>
+ <FontAwesomeIcon icon={icon as any} />
</div>
</div>
);
- }
+ };
- const onPreviewSelected = () => {this._menuContent = 'templates'}
- const onSavedSelected = () => {this._menuContent = 'dashboard'}
+ const onPreviewSelected = () => {
+ this._menuContent = 'templates';
+ };
+ const onSavedSelected = () => {
+ this._menuContent = 'dashboard';
+ };
const onOptionsSelected = () => {
this._menuContent = 'options';
if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length));
- }
-
+ };
return (
- <div className='docCreatorMenu'>
- {!this._shouldDisplay ? undefined :
- <div
- className="docCreatorMenu-cont"
- ref={r => this._ref = r}
- style={{
- display: '',
- left: this._pageX,
- top: this._pageY,
- width: this._menuDimensions.width,
- height: this._menuDimensions.height,
- background: SnappingManager.userBackgroundColor,
- color: SnappingManager.userColor,
- }}>
+ <div className="docCreatorMenu">
+ {!this._shouldDisplay ? undefined : (
+ <div
+ className="docCreatorMenu-cont"
+ ref={r => (this._ref = r)}
+ style={{
+ display: '',
+ left: this._pageX,
+ top: this._pageY,
+ width: this._menuDimensions.width,
+ height: this._menuDimensions.height,
+ background: SnappingManager.userBackgroundColor,
+ color: SnappingManager.userColor,
+ }}>
{this.resizePanes}
- <div
- className='docCreatorMenu-menu'
- onPointerDown={e =>
- setupMoveUpEvents(
- this,
- e,
- (e) => {
- this._dragging = true;
- this._startPos = {x: 0, y: 0};
- this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
- this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
- document.addEventListener('pointermove', this.onDrag);
- return true;
- },
- emptyFunction,
- undoable(clickEv => {
- clickEv.stopPropagation();
- }, 'drag menu')
- )
- }
- >
- <div className='docCreatorMenu-top-buttons-container'>
+ <div
+ className="docCreatorMenu-menu"
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ e => {
+ this._dragging = true;
+ this._startPos = { x: 0, y: 0 };
+ this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
+ this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
+ document.addEventListener('pointermove', this.onDrag);
+ return true;
+ },
+ emptyFunction,
+ undoable(clickEv => {
+ clickEv.stopPropagation();
+ }, 'drag menu')
+ )
+ }>
+ <div className="docCreatorMenu-top-buttons-container">
{topButton('table-cells', 'templates', onPreviewSelected, 'left')}
{topButton('bars', 'options', onOptionsSelected, 'middle')}
{topButton('floppy-disk', 'saved', onSavedSelected, 'right')}
</div>
- <button
- className='docCreatorMenu-menu-button close-menu'
- onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}>
- <FontAwesomeIcon icon={'minus'}/>
+ <button className="docCreatorMenu-menu-button close-menu" onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}>
+ <FontAwesomeIcon icon={'minus'} />
</button>
</div>
{this.renderSelectedViewType}
- </div>
- }
+ </div>
+ )}
</div>
- )
- }
+ );
+ }
}
export interface DataVizTemplateInfo {
doc: Doc;
- layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number};
+ layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
columns: number;
- referencePos: {x: number, y: number};
+ referencePos: { x: number; y: number };
}
export interface DataVizTemplateLayout {
template: Doc;
docsNumList: number[];
- layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number};
+ layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
columns: number;
rows: number;
}
@@ -1453,7 +1573,7 @@ export interface DataVizTemplateLayout {
export enum TemplateFieldType {
TEXT = 'text',
VISUAL = 'visual',
- UNSET = 'unset'
+ UNSET = 'unset',
}
export enum TemplateFieldSize {
@@ -1461,17 +1581,16 @@ export enum TemplateFieldSize {
SMALL = 'small',
MEDIUM = 'medium',
LARGE = 'large',
- HUGE = 'huge'
+ HUGE = 'huge',
}
-
export type Col = {
sizes: TemplateFieldSize[];
desc: string;
title: string;
type: TemplateFieldType;
defaultContent?: string;
-}
+};
type Field = {
tl: [number, number];
@@ -1482,7 +1601,7 @@ type Field = {
sizes?: TemplateFieldSize[];
isDecoration?: boolean;
description?: string;
-}
+};
// class ContentField implements Field {
// tl: [number, number];
@@ -1493,10 +1612,10 @@ type Field = {
// sizes?: TemplateFieldSize[];
// description?: string;
-// constructor( tl: [number, number], br: [number, number],
-// opts: FieldOpts, subfields?: Field[],
-// types?: TemplateFieldType[],
-// sizes?: TemplateFieldSize[],
+// constructor( tl: [number, number], br: [number, number],
+// opts: FieldOpts, subfields?: Field[],
+// types?: TemplateFieldType[],
+// sizes?: TemplateFieldSize[],
// description?: string) {
// this.tl = tl;
// this.br = br;
@@ -1514,9 +1633,7 @@ type Field = {
type DecorationField = Field;
-type InkDecoration = {
-
-}
+type InkDecoration = {};
type TemplateDecorations = Field | InkDecoration;
@@ -1545,85 +1662,86 @@ export interface FieldOpts {
fieldViewType?: 'freeform' | 'stacked';
}
-interface TemplateOpts extends FieldOpts {
-
-}
+interface TemplateOpts extends FieldOpts {}
export class FieldUtils {
-
public static contentFields = (fields: Field[]) => {
let toRet: Field[] = [];
fields.forEach(field => {
- if (!field.isDecoration) { toRet.push(field) };
+ if (!field.isDecoration) {
+ toRet.push(field);
+ }
toRet = toRet.concat(FieldUtils.contentFields(field.subfields ?? []));
});
return toRet;
- }
+ };
public static calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
const words: string[] = text.split(/\s+/).filter(Boolean);
- let currFontSize = 1;
+ 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 * .5;
+ const wordWidth = word.length * currFontSize * 0.5;
//console.log(wordWidth)
-
+
if (currentRowWidth + wordWidth <= contWidth) {
currentRowWidth += wordWidth;
++wordsInCurrRow;
} else {
- if (words.length !== 1 && words.length > wordsInCurrRow){
+ if (words.length !== 1 && words.length > wordsInCurrRow) {
rowsCount++;
- currentRowWidth = wordWidth;
+ currentRowWidth = wordWidth;
wordsInCurrRow = 1;
} else {
break;
}
}
-
- wordIndex++;
+
+ wordIndex++;
}
-
+
currTextHeight = rowsCount * currFontSize * 2;
//console.log(rowsCount, currFontSize, currTextHeight)
-
+
currFontSize += 1;
}
-
+
return currFontSize - 1;
};
- private static getDimensions = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number): {width: number, height: number, coord: {x: number, y: number}} => {
- const l = coords.tl[0] * parentHeight / 2; const t = coords.tl[1] * parentWidth / 2; //prettier-ignore
- const r = coords.br[0] * parentHeight / 2; const b = coords.br[1] * parentWidth / 2; //prettier-ignore
+ private static getDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number): { width: number; height: number; coord: { x: number; y: number } } => {
+ const l = (coords.tl[0] * parentHeight) / 2;
+ const t = coords.tl[1] * parentWidth / 2; //prettier-ignore
+ const r = (coords.br[0] * parentHeight) / 2;
+ const b = coords.br[1] * parentWidth / 2; //prettier-ignore
const width = r - l;
const height = b - t;
- const coord = {x: l, y: t};
+ const coord = { x: l, y: t };
//console.log(coords, parentWidth, parentHeight, height);
- return {width, height, coord};
- }
+ return { width, height, coord };
+ };
- public static FreeformField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
- const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+ public static FreeformField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+ const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
- const docWithBasicOpts = (Docs.Create.FreeformDocument)([], {
- isDefaultTemplateDoc: true,
- _height: height,
- _width: width,
- title: title,
- x: coord.x,
- y: coord.y,
+ const docWithBasicOpts = Docs.Create.FreeformDocument([], {
+ isDefaultTemplateDoc: true,
+ _height: height,
+ _width: width,
+ title: title,
+ x: coord.x,
+ y: coord.y,
backgroundColor: opts.backgroundColor ?? '',
_layout_borderRounding: `${opts.cornerRounding}px` ?? '0px',
borderColor: opts.borderColor,
@@ -1634,21 +1752,21 @@ export class FieldUtils {
});
return docWithBasicOpts;
- }
+ };
- public static TextField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
- const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+ public static TextField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+ const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
const bool = true;
- const docWithBasicOpts = (Docs.Create.TextDocument)(content, {
+ const docWithBasicOpts = Docs.Create.TextDocument(content, {
isDefaultTemplateDoc: true,
- _height: height,
- _width: width,
- title: title,
- x: coord.x,
- y: coord.y,
- _text_fontSize: `${FieldUtils.calculateFontSize(width, height, content, true)}` ,
+ _height: height,
+ _width: width,
+ title: title,
+ x: coord.x,
+ y: coord.y,
+ _text_fontSize: `${FieldUtils.calculateFontSize(width, height, content, true)}`,
backgroundColor: opts.backgroundColor ?? '',
text_fontColor: opts.color,
contentBold: opts.fontBold,
@@ -1665,17 +1783,17 @@ export class FieldUtils {
docWithBasicOpts._layout_hideScroll = true;
return docWithBasicOpts;
- }
+ };
- public static ImageField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
- const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+ public static ImageField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+ const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
- const doc = Docs.Create.ImageDocument(content, {
- isDefaultTemplateDoc: true,
- _height: height,
- _width: width,
- title: title,
- x: coord.x,
+ const doc = Docs.Create.ImageDocument(content, {
+ isDefaultTemplateDoc: true,
+ _height: height,
+ _width: width,
+ title: title,
+ x: coord.x,
y: coord.y,
_layout_fitWidth: false,
backgroundColor: opts.backgroundColor ?? '',
@@ -1689,28 +1807,24 @@ export class FieldUtils {
//setTimeout(() => {doc._height = height; doc._width = width}, 10);
return doc;
- }
+ };
- public static CarouselField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, fields: Doc[]) => {
- const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+ public static CarouselField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, fields: Doc[]) => {
+ const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
- const doc = Docs.Create.Carousel3DDocument(fields, { _height: height, _width: width, title: title, x: coord.x, y: coord.y, _text_fontSize: `${height/2}` })
+ const doc = Docs.Create.Carousel3DDocument(fields, { _height: height, _width: width, title: title, x: coord.x, y: coord.y, _text_fontSize: `${height / 2}` });
return doc;
- }
-
+ };
}
export class TemplateLayouts {
-
public static get allTemplates(): TemplateDocInfos[] {
- return Object.values(TemplateLayouts).filter(
- value => typeof value === 'object' && value !== null && 'title' in value
- ) as TemplateDocInfos[];
+ return Object.values(TemplateLayouts).filter(value => typeof value === 'object' && value !== null && 'title' in value) as TemplateDocInfos[];
}
public static getTemplateByTitle = (title: string): TemplateDocInfos | undefined => {
- switch (title){
+ switch (title) {
case 'fourfield1':
return TemplateLayouts.FourField001;
case 'fourfield2':
@@ -1728,173 +1842,187 @@ export class TemplateLayouts {
}
return undefined;
- }
+ };
public static FourField001: TemplateDocInfos = {
title: 'fourfield1',
- width: 416,
- height: 700,
+ width: 416,
+ height: 700,
opts: {
backgroundColor: '#C0B887',
cornerRounding: 20,
borderColor: '#6B461F',
borderWidth: '12',
},
- fields: [{
- tl: [-.95, -1],
- br: [.95, -.85],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY],
- description: 'A title field for very short text that contextualizes the content.',
- opts: {
- backgroundColor: 'transparent',
- color: '#F1F0E9',
- contentXCentering: 'h-center',
- fontBold: true,
- }
- }, {
- tl: [-.87, -.83],
- br: [.87, .2],
- types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: 'The main focus of the template; could be an image, long text, etc.',
- opts: {
- cornerRounding: 20,
- borderColor: '#8F5B25',
- borderWidth: '6',
- backgroundColor: '#CECAB9',
- }
- }, {
- tl: [-.8, .2],
- br: [.8, .3],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
- description: 'A caption for field #2, very short to short text that contextualizes the content of field #2',
- opts: {
- backgroundColor: 'transparent',
- contentXCentering: 'h-center',
- color: '#F1F0E9',
- }
- }, {
- tl: [-.87, .37],
- br: [.87, .96],
- types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: 'A medium-sized field for medium/long text.',
- opts: {
- cornerRounding: 15,
- borderColor: '#8F5B25',
- borderWidth: '6',
- backgroundColor: '#CECAB9',
- }
- }],
+ fields: [
+ {
+ tl: [-0.95, -1],
+ br: [0.95, -0.85],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY],
+ description: 'A title field for very short text that contextualizes the content.',
+ opts: {
+ backgroundColor: 'transparent',
+ color: '#F1F0E9',
+ contentXCentering: 'h-center',
+ fontBold: true,
+ },
+ },
+ {
+ tl: [-0.87, -0.83],
+ br: [0.87, 0.2],
+ types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+ description: 'The main focus of the template; could be an image, long text, etc.',
+ opts: {
+ cornerRounding: 20,
+ borderColor: '#8F5B25',
+ borderWidth: '6',
+ backgroundColor: '#CECAB9',
+ },
+ },
+ {
+ tl: [-0.8, 0.2],
+ br: [0.8, 0.3],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+ description: 'A caption for field #2, very short to short text that contextualizes the content of field #2',
+ opts: {
+ backgroundColor: 'transparent',
+ contentXCentering: 'h-center',
+ color: '#F1F0E9',
+ },
+ },
+ {
+ tl: [-0.87, 0.37],
+ br: [0.87, 0.96],
+ types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+ description: 'A medium-sized field for medium/long text.',
+ opts: {
+ cornerRounding: 15,
+ borderColor: '#8F5B25',
+ borderWidth: '6',
+ backgroundColor: '#CECAB9',
+ },
+ },
+ ],
decorations: [],
};
public static FourField002: TemplateDocInfos = {
title: 'fourfield2',
- width: 425,
- height: 778,
+ width: 425,
+ height: 778,
opts: {
- backgroundColor: '#242425'
+ backgroundColor: '#242425',
},
- fields: [{
- tl: [-.83, -.95],
- br: [.83, -.2],
- types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
- 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',
- borderColor: '#F8E71C',
- }
- }, {
- tl: [-.65, -.2],
- br: [.65, -.02],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY],
- description: 'A tiny field for just a word or two of plain text.',
- opts: {
- backgroundColor: 'transparent',
- color: 'white',
- contentXCentering: 'h-center',
- fontTransform: 'uppercase'
- }
- }, {
- tl: [-.65, 0],
- br: [.65, .18],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY],
- description: 'A tiny field for just a word or two of plain text.',
- opts: {
- backgroundColor: 'transparent',
- color: 'white',
- contentXCentering: 'h-center',
- fontTransform: 'uppercase'
- }
- }, {
- tl: [-.83, .2],
- br: [.83, .95],
- types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus, or share focus with field 1.',
- opts: {
- borderWidth: '8',
- borderColor: '#F8E71C',
- color: 'white',
- backgroundColor: '#242425',
- }
- }],
- decorations: [{
- tl: [-.8, -.075],
- br: [-.525, .075],
- opts: {
- backgroundColor: '#F8E71C',
- rotation: 45
- }
- }, {
- tl: [-.3075, -.0245],
- br: [-.2175, .0245],
- opts: {
- backgroundColor: '#F8E71C',
- rotation: 45
- }
- }, {
- tl: [-.045, -.0245],
- br: [.045, .0245],
- opts: {
- backgroundColor: '#F8E71C',
- rotation: 45
- }
- }, {
- tl: [.2175, -.0245],
- br: [.3075, .0245],
- opts: {
- backgroundColor: '#F8E71C',
- rotation: 45
- }
- }, {
- tl: [.525, -.075],
- br: [.8, .075],
- opts: {
- backgroundColor: '#F8E71C',
- rotation: 45
- }
- }
-
- ]
+ fields: [
+ {
+ tl: [-0.83, -0.95],
+ br: [0.83, -0.2],
+ types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
+ 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',
+ borderColor: '#F8E71C',
+ },
+ },
+ {
+ tl: [-0.65, -0.2],
+ br: [0.65, -0.02],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY],
+ description: 'A tiny field for just a word or two of plain text.',
+ opts: {
+ backgroundColor: 'transparent',
+ color: 'white',
+ contentXCentering: 'h-center',
+ fontTransform: 'uppercase',
+ },
+ },
+ {
+ tl: [-0.65, 0],
+ br: [0.65, 0.18],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY],
+ description: 'A tiny field for just a word or two of plain text.',
+ opts: {
+ backgroundColor: 'transparent',
+ color: 'white',
+ contentXCentering: 'h-center',
+ fontTransform: 'uppercase',
+ },
+ },
+ {
+ tl: [-0.83, 0.2],
+ br: [0.83, 0.95],
+ types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+ description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus, or share focus with field 1.',
+ opts: {
+ borderWidth: '8',
+ borderColor: '#F8E71C',
+ color: 'white',
+ backgroundColor: '#242425',
+ },
+ },
+ ],
+ decorations: [
+ {
+ tl: [-0.8, -0.075],
+ br: [-0.525, 0.075],
+ opts: {
+ backgroundColor: '#F8E71C',
+ rotation: 45,
+ },
+ },
+ {
+ tl: [-0.3075, -0.0245],
+ br: [-0.2175, 0.0245],
+ opts: {
+ backgroundColor: '#F8E71C',
+ rotation: 45,
+ },
+ },
+ {
+ tl: [-0.045, -0.0245],
+ br: [0.045, 0.0245],
+ opts: {
+ backgroundColor: '#F8E71C',
+ rotation: 45,
+ },
+ },
+ {
+ tl: [0.2175, -0.0245],
+ br: [0.3075, 0.0245],
+ opts: {
+ backgroundColor: '#F8E71C',
+ rotation: 45,
+ },
+ },
+ {
+ tl: [0.525, -0.075],
+ br: [0.8, 0.075],
+ opts: {
+ backgroundColor: '#F8E71C',
+ rotation: 45,
+ },
+ },
+ ],
};
// public static FourField003: TemplateDocInfos = {
// title: 'fourfield3',
- // width: 477,
- // height: 662,
+ // width: 477,
+ // height: 662,
// opts: {
// backgroundColor: '#9E9C95'
// },
// fields: [{
- // tl: [-.875, -.9],
- // br: [.875, .7],
+ // tl: [-.875, -.9],
+ // br: [.875, .7],
// types: [TemplateFieldType.VISUAL],
// sizes: [TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
// description: '',
@@ -1903,8 +2031,8 @@ export class TemplateLayouts {
// borderColor: '#E0E0DA',
// }
// }, {
- // tl: [-.95, .8],
- // br: [-.1, .95],
+ // tl: [-.95, .8],
+ // br: [-.1, .95],
// types: [TemplateFieldType.TEXT],
// sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
// description: '',
@@ -1914,8 +2042,8 @@ export class TemplateLayouts {
// contentXCentering: 'h-right',
// }
// }, {
- // tl: [.1, .8],
- // br: [.95, .95],
+ // tl: [.1, .8],
+ // br: [.95, .95],
// types: [TemplateFieldType.TEXT],
// sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
// description: '',
@@ -1926,8 +2054,8 @@ export class TemplateLayouts {
// contentXCentering: 'h-left'
// }
// }, {
- // tl: [0, -.9],
- // br: [.85, -.66],
+ // tl: [0, -.9],
+ // br: [.85, -.66],
// types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
// sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
// description: '',
@@ -1937,8 +2065,8 @@ export class TemplateLayouts {
// }
// }],
// decorations: [{
- // tl: [-.025, .8],
- // br: [.025, .95],
+ // tl: [-.025, .8],
+ // br: [.025, .95],
// opts: {
// backgroundColor: '#E0E0DA',
// }
@@ -1947,242 +2075,257 @@ export class TemplateLayouts {
public static FourField004: TemplateDocInfos = {
title: 'fourfield4',
- width: 414,
- height: 583,
+ width: 414,
+ height: 583,
opts: {
backgroundColor: '#6CCAF0',
borderColor: '#1088C3',
- borderWidth: '10'
+ borderWidth: '10',
},
- fields: [{
- tl: [-.86, -.92],
- br: [-.075, -.77],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY],
- description: 'A tiny field for just a word or two of plain text.',
- opts: {
- backgroundColor: '#E2B4F5',
- borderWidth: '9',
- borderColor: '#9222F1',
- contentXCentering: 'h-center'
- }
- }, {
- tl: [.075, -.92],
- br: [.86, -.77],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY],
- description: 'A tiny field for just a word or two of plain text.',
- opts: {
- backgroundColor: '#F5B4DD',
- borderWidth: '9',
- borderColor: '#E260F3',
- contentXCentering: 'h-center'
- }
- }, {
- tl: [-.81, -.64],
- br: [.81, .48],
- types: [TemplateFieldType.VISUAL],
- 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',
- borderColor: '#A2BD77',
- }
- }, {
- tl: [-.86, .6],
- br: [.86, .92],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
- description: 'A medium to large field for text that describes the visual content above',
- opts: {
- borderWidth: '9',
- borderColor: '#F0D601',
- backgroundColor: '#F3F57D',
- }
- }],
- decorations: [{
- tl: [-.852, -.67],
- br: [.852, .51],
- opts: {
- backgroundColor: 'transparent',
- borderColor: '#007C0C',
- borderWidth: '10',
- }
- }]
+ fields: [
+ {
+ tl: [-0.86, -0.92],
+ br: [-0.075, -0.77],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY],
+ description: 'A tiny field for just a word or two of plain text.',
+ opts: {
+ backgroundColor: '#E2B4F5',
+ borderWidth: '9',
+ borderColor: '#9222F1',
+ contentXCentering: 'h-center',
+ },
+ },
+ {
+ tl: [0.075, -0.92],
+ br: [0.86, -0.77],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY],
+ description: 'A tiny field for just a word or two of plain text.',
+ opts: {
+ backgroundColor: '#F5B4DD',
+ borderWidth: '9',
+ borderColor: '#E260F3',
+ contentXCentering: 'h-center',
+ },
+ },
+ {
+ tl: [-0.81, -0.64],
+ br: [0.81, 0.48],
+ types: [TemplateFieldType.VISUAL],
+ 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',
+ borderColor: '#A2BD77',
+ },
+ },
+ {
+ tl: [-0.86, 0.6],
+ br: [0.86, 0.92],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+ description: 'A medium to large field for text that describes the visual content above',
+ opts: {
+ borderWidth: '9',
+ borderColor: '#F0D601',
+ backgroundColor: '#F3F57D',
+ },
+ },
+ ],
+ decorations: [
+ {
+ tl: [-0.852, -0.67],
+ br: [0.852, 0.51],
+ opts: {
+ backgroundColor: 'transparent',
+ borderColor: '#007C0C',
+ borderWidth: '10',
+ },
+ },
+ ],
};
public static ThreeField001: TemplateDocInfos = {
title: 'threefield1',
- width: 575,
- height: 770,
+ width: 575,
+ height: 770,
opts: {
- backgroundColor: '#DDD3A9'
+ backgroundColor: '#DDD3A9',
},
- fields: [{
- tl: [-.66, -.747],
- br: [.66, .247],
- 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: {
- borderColor: 'yellow',
- borderWidth: '8',
- rotation: 45,
+ fields: [
+ {
+ tl: [-0.66, -0.747],
+ br: [0.66, 0.247],
+ 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: {
+ borderColor: 'yellow',
+ borderWidth: '8',
+ rotation: 45,
+ },
},
- }, {
- tl: [-.7, .2],
- br: [.7, .46],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
- description: 'A very small text field for one to a few words. A good caption for the image.',
- opts: {
- backgroundColor: 'transparent',
- contentXCentering: 'h-center',
- }
- }, {
- tl: [-.95, .5],
- br: [.95, .95],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
- description: 'A medium to large text field for a thorough description of the image. ',
- opts: {
- backgroundColor: 'transparent',
- color: 'white'
- }
- }],
- decorations: [{
- tl: [.2, -1.32],
- br: [1.8, -.66],
- opts: {
- backgroundColor: '#CEB155',
- rotation: 45,
- }
- }, {
- tl: [-1.8, -1.32],
- br: [-.2, -.66],
- opts: {
- backgroundColor: '#CEB155',
- rotation: 135,
- }
- }, {
- tl: [.33, .75],
- br: [1.66, 1.25],
- opts: {
- backgroundColor: '#CEB155',
- rotation: 135,
- }
- }, {
- tl: [-1.66, .75],
- br: [-.33, 1.25],
- opts: {
- backgroundColor: '#CEB155',
- rotation: 45,
- }
- }]
+ {
+ tl: [-0.7, 0.2],
+ br: [0.7, 0.46],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+ description: 'A very small text field for one to a few words. A good caption for the image.',
+ opts: {
+ backgroundColor: 'transparent',
+ contentXCentering: 'h-center',
+ },
+ },
+ {
+ tl: [-0.95, 0.5],
+ br: [0.95, 0.95],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+ description: 'A medium to large text field for a thorough description of the image. ',
+ opts: {
+ backgroundColor: 'transparent',
+ color: 'white',
+ },
+ },
+ ],
+ decorations: [
+ {
+ tl: [0.2, -1.32],
+ br: [1.8, -0.66],
+ opts: {
+ backgroundColor: '#CEB155',
+ rotation: 45,
+ },
+ },
+ {
+ tl: [-1.8, -1.32],
+ br: [-0.2, -0.66],
+ opts: {
+ backgroundColor: '#CEB155',
+ rotation: 135,
+ },
+ },
+ {
+ tl: [0.33, 0.75],
+ br: [1.66, 1.25],
+ opts: {
+ backgroundColor: '#CEB155',
+ rotation: 135,
+ },
+ },
+ {
+ tl: [-1.66, 0.75],
+ br: [-0.33, 1.25],
+ opts: {
+ backgroundColor: '#CEB155',
+ rotation: 45,
+ },
+ },
+ ],
};
public static ThreeField002: TemplateDocInfos = {
title: 'threefield2',
- width: 477,
- height: 662,
+ width: 477,
+ height: 662,
opts: {
- backgroundColor: '#9E9C95'
+ backgroundColor: '#9E9C95',
},
- fields: [{
- tl: [-.875, -.9],
- br: [.875, .7],
- types: [TemplateFieldType.VISUAL],
- sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: 'A medium to large visual field for the main content of the template',
- opts: {
- borderWidth: '15',
- borderColor: '#E0E0DA',
- }
- }, {
- tl: [.1, .775],
- br: [.95, .975],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
- 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'
- }
- }, {
- tl: [-.95, .775],
- br: [-.1, .975],
- types: [TemplateFieldType.TEXT],
- sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
- 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'
- }
- }],
- decorations: [{
- tl: [-.025, .8],
- br: [.025, .95],
- opts: {
- backgroundColor: '#E0E0DA',
- }
- }]
+ fields: [
+ {
+ tl: [-0.875, -0.9],
+ br: [0.875, 0.7],
+ types: [TemplateFieldType.VISUAL],
+ sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+ description: 'A medium to large visual field for the main content of the template',
+ opts: {
+ borderWidth: '15',
+ borderColor: '#E0E0DA',
+ },
+ },
+ {
+ tl: [0.1, 0.775],
+ br: [0.95, 0.975],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+ 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',
+ },
+ },
+ {
+ tl: [-0.95, 0.775],
+ br: [-0.1, 0.975],
+ types: [TemplateFieldType.TEXT],
+ sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+ 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',
+ },
+ },
+ ],
+ decorations: [
+ {
+ tl: [-0.025, 0.8],
+ br: [0.025, 0.95],
+ opts: {
+ backgroundColor: '#E0E0DA',
+ },
+ },
+ ],
};
-
-
-// public static FourField002: TemplateDocInfos = {
-// width: 450,
-// height: 600,
-// fields: [{
-// tl: [-.6, -.9],
-// br: [.6, -.8],
-// types: [FieldType.TEXT],
-// sizes: [FieldSize.TINY]
-// }, {
-// tl: [-.9, -.7],
-// br: [.9, .2],
-// types: [FieldType.TEXT, FieldType.VISUAL],
-// sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
-// }, {
-// tl: [-.9, .3],
-// br: [-.05, .9],
-// types: [FieldType.TEXT],
-// sizes: [FieldSize.TINY]
-// }, {
-// tl: [.05, .3],
-// br: [.9, .9],
-// types: [FieldType.TEXT, FieldType.VISUAL],
-// sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
-// }]
-// };
-
-// public static TwoFieldPlusCarousel: TemplateDocInfos = {
-// width: 500,
-// height: 600,
-// fields: [{
-// tl: [-.9, -.99],
-// br: [.9, -.7],
-// types: [FieldType.TEXT],
-// sizes: [FieldSize.TINY]
-// }, {
-// tl: [-.9, -.65],
-// br: [.9, .35],
-// types: [],
-// sizes: []
-// }, {
-// tl: [-.9, .4],
-// br: [.9, .95],
-// types: [FieldType.TEXT],
-// sizes: [FieldSize.TINY]
-// }]
-// };
-
+ // public static FourField002: TemplateDocInfos = {
+ // width: 450,
+ // height: 600,
+ // fields: [{
+ // tl: [-.6, -.9],
+ // br: [.6, -.8],
+ // types: [FieldType.TEXT],
+ // sizes: [FieldSize.TINY]
+ // }, {
+ // tl: [-.9, -.7],
+ // br: [.9, .2],
+ // types: [FieldType.TEXT, FieldType.VISUAL],
+ // sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
+ // }, {
+ // tl: [-.9, .3],
+ // br: [-.05, .9],
+ // types: [FieldType.TEXT],
+ // sizes: [FieldSize.TINY]
+ // }, {
+ // tl: [.05, .3],
+ // br: [.9, .9],
+ // types: [FieldType.TEXT, FieldType.VISUAL],
+ // sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
+ // }]
+ // };
+
+ // public static TwoFieldPlusCarousel: TemplateDocInfos = {
+ // width: 500,
+ // height: 600,
+ // fields: [{
+ // tl: [-.9, -.99],
+ // br: [.9, -.7],
+ // types: [FieldType.TEXT],
+ // sizes: [FieldSize.TINY]
+ // }, {
+ // tl: [-.9, -.65],
+ // br: [.9, .35],
+ // types: [],
+ // sizes: []
+ // }, {
+ // tl: [-.9, .4],
+ // br: [.9, .95],
+ // types: [FieldType.TEXT],
+ // sizes: [FieldSize.TINY]
+ // }]
+ // };
}
-
-export class ContentField extends Field {
-
-} \ No newline at end of file