aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
diff options
context:
space:
mode:
authorNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-10-01 04:01:07 -0400
committerNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-10-01 04:01:07 -0400
commit96883cb177d44ed9e06e800de9b35bda36e6fd1c (patch)
treeb9c13734c07e25dbeb99c0fbebee0e3b8be09c00 /src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
parent115c243e57dd490dfcf09930913a941ca7ecfabc (diff)
parent63e8e1fd38835d193930bc6103a12dc4cf4d8934 (diff)
Merge branch 'nathan-starter' of https://github.com/brown-dash/Dash-Web into nathan-starter
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx')
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx2113
1 files changed, 1130 insertions, 983 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
index 0f93a4dd6..43e9248a7 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,261 @@ 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
+// }