aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx')
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx190
1 files changed, 146 insertions, 44 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
index 191b387c4..33d9a8827 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
@@ -31,6 +31,7 @@ import { dropActionType } from '../../../util/DropActionTypes';
import { ImageBox } from '../ImageBox';
import { a } from '@react-spring/web';
import { RichTextMenu } from '../formattedText/RichTextMenu';
+import e from 'cors';
export enum LayoutType {
Stacked = 'stacked',
@@ -137,8 +138,22 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
@computed get fieldsInfos(): Col[] {
const colInfo = this._dataViz?.colsInfo;
- return this.selectedFields.map(field => {return {title: field, type: colInfo?.get(field)?.type ?? TemplateFieldType.UNSET, desc: colInfo?.get(field)?.desc ?? '', size: colInfo?.get(field)?.size ?? TemplateFieldSize.MEDIUM, defaultContent: colInfo?.get(field)?.defaultContent ?? ''}});
- //.concat(this._columns)
+ return this.selectedFields.map(field => {
+ const fieldInfo = colInfo?.get(field);
+
+ const col: Col = {
+ title: field,
+ type: fieldInfo?.type ?? TemplateFieldType.UNSET,
+ desc: fieldInfo?.desc ?? '',
+ size: fieldInfo?.size ?? TemplateFieldSize.MEDIUM
+ };
+
+ if (fieldInfo?.defaultContent !== undefined) {
+ col.defaultContent = fieldInfo.defaultContent;
+ }
+
+ return col;
+ }).concat(this._columns);
}
@computed get canMakeDocs(){
@@ -463,7 +478,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
}
};
- setFieldType = (column: Col, type: TemplateFieldType) => {
+ setColType = (column: Col, type: TemplateFieldType) => {
if (this.selectedFields.includes(column.title)) {
this._dataViz?.setColumnType(column.title, type);
} else {
@@ -472,7 +487,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this.forceUpdate();
};
- setFieldSize = (column: Col, size: TemplateFieldSize) => {
+ setColSize = (column: Col, size: TemplateFieldSize) => {
if (this.selectedFields.includes(column.title)) {
this._dataViz?.setColumnSize(column.title, size);
} else {
@@ -481,11 +496,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this.forceUpdate();
};
- setFieldDesc = (column: Col, desc: string) => {
+ setColDesc = (column: Col, desc: string) => {
if (this.selectedFields.includes(column.title)) {
this._dataViz?.setColumnDesc(column.title, desc);
} else {
column.desc = desc;
+ console.log(column, column.desc)
}
this.forceUpdate();
};
@@ -578,11 +594,45 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
// return new Doc;
// }
- createEmptyTemplate = (template: TemplateDocInfos, assignments: {[field: string]: Col}): Doc => {
+ fillPresetTemplate = async(template: TemplateDocInfos, assignments: {[field: string]: Col}): Promise<Doc> => {
+ const wordLimit = (size: TemplateFieldSize) => {
+ switch (size) {
+ case TemplateFieldSize.TINY:
+ return 2;
+ case TemplateFieldSize.SMALL:
+ return 5;
+ case TemplateFieldSize.MEDIUM:
+ return 20;
+ case TemplateFieldSize.LARGE:
+ return 50;
+ case TemplateFieldSize.HUGE:
+ return 100;
+ default:
+ return 10;
+ }
+ }
+
const fields: Doc[] = [];
- Object.entries(assignments).forEach(([f, col]) => {
+ const GPTAssignments = Object.entries(assignments).filter(([f, col]) => this._columns.includes(col));
+ const nonGPTAssignments: [string, Col][] = Object.entries(assignments).filter(a => !GPTAssignments.includes(a));
+
+ const stringifyGPTInfo = (): string => {
+ let string: string = '*** COLUMN INFO:';
+ GPTAssignments.forEach(([fieldNum, col]) => {
+ `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.size)} words, assigned field: ${fieldNum} ---`
+ });
+ return string += ' ***';
+ };
+
+ const GPTAssignmentString = stringifyGPTInfo();
+ console.log('assignment string', GPTAssignmentString);
+
+ let fieldContent: string = '';
+
+ Object.entries(nonGPTAssignments).forEach(([f, strCol]) => {
const field: Field = template.fields[Number(f)];
+ const col = strCol[1];
const doc = (col.type === TemplateFieldType.VISUAL ? FieldFuncs.ImageField : FieldFuncs.TextField)({
tl: field.tl,
@@ -594,6 +644,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
field.opts
);
+ fieldContent += `--- Field #${f} (title: ${col.title}): ${col.defaultContent ?? ''} ---`
+
fields.push(doc);
});
@@ -611,21 +663,67 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
fields.push(doc);
});
- const renderedTemplate = Docs.Create.FreeformDocument(fields, {
- _height: template.height,
- _width: template.width,
- title: template.title,
- backgroundColor: template.opts.backgroundColor,
- _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px',
- borderWidth: template.opts.borderWidth,
- borderColor: template.opts.borderColor,
- x: 400,
- y: 400,
- });
+ const createMainDoc = (): Doc => {
+ 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',
+ borderWidth: template.opts.borderWidth,
+ borderColor: template.opts.borderColor,
+ x: 400,
+ y: 400,
+ });
- const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
- mainCollection.addDocument(renderedTemplate);
- return renderedTemplate;
+ const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
+ mainCollection.addDocument(main);
+
+ return main;
+ }
+
+ console.log('field content', fieldContent)
+
+ if (GPTAssignments.length) {
+
+ try {
+ const prompt = fieldContent + GPTAssignmentString;
+
+ const res = await gptAPICall(prompt, GPTCallType.FILL);
+
+ if (res){
+ console.log('response', res);
+
+ const assignments: {[title: string]: {number: string, content: string}} = JSON.parse(res);
+ console.log('assignments', assignments);
+ Object.entries(assignments).forEach(([title, info]) => {
+ const field: Field = template.fields[Number(info.number)];
+ const col = this.getColByTitle(title);
+
+ const doc = (col.type === TemplateFieldType.VISUAL ? FieldFuncs.ImageField : FieldFuncs.TextField)({
+ tl: field.tl,
+ br: field.br },
+ template.height,
+ template.width,
+ col.title,
+ info.content ?? '',
+ field.opts
+ );
+
+ fields.push(doc);
+ });
+
+ return createMainDoc();
+ }
+ } catch(err) {
+ console.log(err);
+ }
+
+ } else {
+ return createMainDoc();
+ }
+
+ return new Doc;
};
compileFieldDescriptions = (templates: TemplateDocInfos[]): string => {
@@ -693,17 +791,21 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
return [];
};
- generatePresetTemplates = async() => {
+ generatePresetTemplates = async () => {
const cols = this.fieldsInfos;
const templates = this.findValidTemplates(cols, TemplateLayouts.allTemplates);
- const assignments: [TemplateDocInfos, {[field: number]: Col}][] = await this.assignColsToFields(templates, cols);
- const renderedTemplates: Doc[] = [];
- assignments.forEach(([template, assignments]) => {
- renderedTemplates.push(this.createEmptyTemplate(template, assignments));
- });
-
- setTimeout(() => {this.setGSuggestedTemplates(renderedTemplates)});
- }
+
+ const assignments: [TemplateDocInfos, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
+
+ const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) =>
+ this.fillPresetTemplate(template, assignments)
+ );
+
+ const renderedTemplates: Doc[] = await Promise.all(renderedTemplatePromises);
+
+ setTimeout(() => { this.setGSuggestedTemplates(renderedTemplates) });
+ };
+
get templatesPreviewContents(){
const renderedTemplates: Doc[] = [];
@@ -1067,15 +1169,15 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
{field.type === TemplateFieldType.UNSET ? <span className='placeholder'>Select media type</span> : null}
<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.setFieldType(field, TemplateFieldType.TEXT)}}/>
+ <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.setFieldType(field, TemplateFieldType.VISUAL)}}/>
+ <input className='bubble' type="radio" name="type" onClick={() => {this.setColType(field, TemplateFieldType.VISUAL)}}/>
<div className='text'>File</div>
</div>
</div>
<input className='field-property-container' id={`${Math.random() * 100}`} placeholder={this._dataViz?.GPTSummary?.get(field.title)?.size} style={{width: field.title === '' ? '30%' : ''}}/>
</div>
- <textarea className='field-description-container' onChange={(e) => this._dataViz?.setColumnDesc(field.title, 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.'} />
+ <textarea className='field-description-container' 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>
<button className='docCreatorMenu-menu-button section-reveal-options top-right' onPointerDown={e => this.setUpButtonClick(e, () => this.removeField(field))}>
<FontAwesomeIcon icon='trash'/>
@@ -1821,37 +1923,37 @@ export class TemplateLayouts {
backgroundColor: '#9E9C95'
},
fields: [{
- tl: [-.95, .8],
- br: [-.1, .95],
+ tl: [-.875, -.9],
+ br: [.875, .7],
types: [TemplateFieldType.VISUAL],
sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
- description: '',
+ description: 'A medium to large visual field for the main content of the template',
opts: {
- backgroundColor: 'transparent',
- color: 'white',
- contentXCentering: 'h-right',
+ borderWidth: '15',
+ borderColor: '#E0E0DA',
}
}, {
- tl: [.1, .8],
- br: [.95, .95],
+ 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: 'red',
+ color: '#AF0D0D',
fontTransform: 'uppercase',
fontBold: true,
contentXCentering: 'h-left'
}
}, {
- tl: [0, -.9],
- br: [.85, -.66],
+ 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'
}
}],