aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2025-05-12 07:26:51 -0400
committerNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2025-05-12 07:26:51 -0400
commit03d1cd8d220fbb27acb49a3ff9e791db9292b83c (patch)
tree54e6d0f434fa88f5d5cdd5c5c16ebeade739c2c4
parent259aaed6bdb77872c40d5c1ea63af741eb52fd4c (diff)
c
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss2
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx37
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ConditionalsTextarea.tsx65
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx15
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts29
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts8
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts6
-rw-r--r--src/client/views/smartdraw/DrawingFillHandler.tsx6
8 files changed, 149 insertions, 19 deletions
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
index 2f7b68c4d..5232ad41c 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
@@ -388,7 +388,7 @@
justify-content: center;
align-items: center;
position: absolute;
- width: calc(100% - 10px);
+ left: 50%;
bottom: 0px;
margin: 0px;
margin-bottom: 10px;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index b024a6e9b..bd5c50aa0 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -38,6 +38,7 @@ import { TemplateMenuAIUtils } from './Backend/TemplateMenuAIUtils'
import { TemplatePreviewGrid } from './Menu/TemplatePreviewGrid';
import { FireflyStructureOptions, TemplateEditingWindow } from './Menu/TemplateEditingWindow';
import { DocCreatorMenuButton } from './Menu/DocCreatorMenuButton';
+import { ConditionalsTextArea } from './Menu/ConditionalsTextarea';
export enum LayoutType {
FREEFORM = 'Freeform',
@@ -91,6 +92,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
@observable _userTemplates: Template[] = [];
@observable _selectedTemplate: Template | undefined = undefined;
@observable _currEditingTemplate: Template | undefined = undefined;
+ @observable _editedTemplateTrail: Template[] = [];
@observable _userCreatedFields: Col[] = [];
@observable _collapsedCols: String[] = []; //any columns whose options panels are hidden
@@ -589,8 +591,6 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
this.variations = [];
const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
- console.log('styleref: ', useStyleRef);
-
const clone: Doc = (await Doc.MakeClone(onDoc)).clone;
mainCollection.addDocument(clone);
clone.x = 10000;
@@ -618,15 +618,19 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
}
};
+ @action editLastTemplate = () => { if (this._editedTemplateTrail.length) this._currEditingTemplate = this._editedTemplateTrail.pop()}
+
@action setExpandedView = (template: Template | undefined) => {
- this._currEditingTemplate = template;
if (template) {
this._menuContent = 'templateEditing';
+ this._currEditingTemplate && this._editedTemplateTrail.push(this._currEditingTemplate);
} else {
this._menuContent = 'templates';
}
+ this._currEditingTemplate = template;
+
//Docs.Create.FreeformDocument([doc], { _height: NumListCast(doc._height)[0], _width: NumListCast(doc._width)[0], title: ''});
};
@@ -910,15 +914,26 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
);
}
+ private _newCondCache: Record<string, Conditional> = {};
+
+ getParams = (title: string, parameters?: Conditional): Conditional => {
+ if (parameters) return parameters;
+
+ if (!this._newCondCache[title]) {
+ this._newCondCache[title] = { field: title, operator: '=', condition: '', target: '', attribute: '', value: '' };
+ }
+ return this._newCondCache[title];
+ };
+
get dashboardContents() {
const contentFieldTitles = this.fieldsInfos.filter(field => field.type !== TemplateFieldType.DATA).map(field => field.title).concat('Template');
const conditionForm = (title: string, parameters?: Conditional, empty: boolean = false) => {
- const params: Conditional = parameters ?? this._currEditingConditional;
+ const params: Conditional = this.getParams(title, parameters);
return (
- <div className='form' id={String(Math.random() * 100000)}>
+ <div className='form'>
<div className='form-row'>
<div className='form-row-plain-text'>If</div>
<div className='form-row-plain-text'>{title}</div>
@@ -929,7 +944,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
<div className='operator-dropdown-option' onPointerDown={() => {params.operator = '<'}}>{'<'}</div>
<div className='operator-dropdown-option' onPointerDown={() => {params.operator = 'contains'}}>{'has'}</div>
</div>
- <textarea
+ <input
className="form-row-textarea"
onChange={e => runInAction(() => params.condition = e.target.value)}
placeholder='value'
@@ -957,9 +972,9 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
/>
</div>
{empty ?
- <DocCreatorMenuButton icon={'plus'} styles={'float-right'} function={() => this.templateManager.addFieldCondition(title, params)}/>
+ <DocCreatorMenuButton icon={'plus'} styles={'float-right border'} function={() => this.templateManager.addFieldCondition(title, params)}/>
:
- <DocCreatorMenuButton icon={'minus'} styles={'float-right'} function={() => this.templateManager.removeFieldCondition(title, params)}/>
+ <DocCreatorMenuButton icon={'minus'} styles={'float-right border'} function={() => this.templateManager.removeFieldCondition(title, params)}/>
}
</div>
)
@@ -1032,7 +1047,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
}
<div className="conditionals-section">
<span className="conditionals-title">Conditional Logic</span>
- {conditionForm(field.title, this._currEditingConditional, true)}
+ {conditionForm(field.title, undefined, true)}
{this.templateManager.conditionalFieldLogic[field.title]?.map(condition => conditionForm(condition.field, condition))}
</div>
</>
@@ -1053,6 +1068,8 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
@computed get editingView() { return <TemplateEditingWindow template={this._currEditingTemplate as Template} menu={this} /> }
+ private optionsButtonOpts: [IconProp, () => any] = ['gear', () => (this._menuContent = 'dashboard')];
+
get renderSelectedViewType() {
switch (this._menuContent) {
case 'templates':
@@ -1063,7 +1080,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
title={'Suggested Templates'}
menu={this}
loading={this._GPTLoading}
- optionsButtonOpts={['gear', () => (this._menuContent = 'dashboard')]}
+ optionsButtonOpts={this.optionsButtonOpts}
templates={this._suggestedTemplates}
/>
<div className="docCreatorMenu-GPT-options">
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ConditionalsTextarea.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ConditionalsTextarea.tsx
new file mode 100644
index 000000000..2ca0bde3f
--- /dev/null
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/ConditionalsTextarea.tsx
@@ -0,0 +1,65 @@
+import { observer } from "mobx-react";
+import { ObservableReactComponent } from "../../../../ObservableReactComponent";
+import { Conditional } from "../Backend/TemplateManager";
+import { action, makeObservable, observable, runInAction } from "mobx";
+import React from "react";
+
+interface ConditionalsTextAreaProps {
+ conditional: Conditional;
+ property: keyof Conditional;
+}
+
+@observer
+export class ConditionalsTextArea extends ObservableReactComponent<ConditionalsTextAreaProps> {
+
+ private mirrorRef: HTMLSpanElement | null = null;
+
+ @observable private inputWidth: string = '60px';
+
+ constructor(props: ConditionalsTextAreaProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ setMirrorRef: React.LegacyRef<HTMLSpanElement> = (node) => { this.mirrorRef = node }
+
+ @action updateInputWidth() {
+ const mirror = this.mirrorRef;
+ if (mirror) {
+ const width = mirror.offsetWidth;
+ if ( width + 8 > 60) this.inputWidth = `${width + 8}px`;
+ }
+ }
+
+ render() {
+ return (
+ <div style={{ display: 'inline-block', position: 'relative' }}>
+ <span
+ ref={this.setMirrorRef}
+ style={{
+ position: 'absolute',
+ visibility: 'hidden',
+ whiteSpace: 'pre',
+ font: 'inherit',
+ padding: 0,
+ }}
+ >
+ {this._props.conditional[this._props.property] || ' '}
+ </span>
+ <input
+ className="form-row-input"
+ value={this.props.conditional[this.props.property] ?? ''}
+ onChange={e => {
+ runInAction(() => {
+ this.props.conditional[this.props.property] = e.target.value as any;
+ });
+ this.updateInputWidth();
+ }}
+ style={{ width: this.inputWidth }}
+ placeholder={this.props.property}
+ />
+ </div>
+ );
+ }
+
+} \ No newline at end of file
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
index e1d8ea8a5..cb87e9b47 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx
@@ -17,6 +17,8 @@ import { IDisposer } from "mobx-utils";
import { ImageField } from "../../../../../../fields/URLField";
import { DocCreatorMenuButton } from "./DocCreatorMenuButton";
import { TbHistory } from "react-icons/tb";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { docStyle } from "pdfjs-dist/types/web/ui_utils";
export type FireflyStructureOptions = {
numVariations: number;
@@ -50,7 +52,9 @@ export class FireflyVariationsTab extends ObservableReactComponent<FireflyVariat
generateVariations = async () => {
this._props.menu._variations = [];
this._loading = true;
- const doc: Doc = this._props.template.clone(false).getRenderedDoc()!;
+ const cloneTemplate = this._props.template.clone(false);
+ cloneTemplate.setMatteBackground();
+ const doc: Doc = cloneTemplate.getRenderedDoc()!;
this._variationURLs = await this._props.menu.generateVariations(doc, this.prompt, this.fireflyOptions);
this._variationURLs.forEach(url => {
const newTemplate: Template = this._props.template.clone(true);
@@ -68,6 +72,9 @@ export class FireflyVariationsTab extends ObservableReactComponent<FireflyVariat
this.promptInput = node;
}
+ private optionsButtonOpts: [IconProp, () => any] = ['gear', () => {}];
+ private previewBoxRightButtonOpts: [IconProp, () => any] = ['gear', () => this.forceUpdate()];
+
render() {
return (
<div className='docCreatorMenu-editing-firefly-section'>
@@ -78,8 +85,8 @@ export class FireflyVariationsTab extends ObservableReactComponent<FireflyVariat
loading={this._loading}
styles={'scrolling'}
templates={this._props.menu._variations}
- optionsButtonOpts={['gear', () => {}]}
- previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]}
+ optionsButtonOpts={this.optionsButtonOpts}
+ previewBoxRightButtonOpts={this.previewBoxRightButtonOpts}
/>
<div className="docCreatorMenu-firefly-options">
<div className="docCreatorMenu-variation-prompt-row">
@@ -226,7 +233,7 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit
this._props.menu.setExpandedView(undefined);
}}/>
<DocCreatorMenuButton icon={'lightbulb'} function={() => this.setVariationTab(!this._variationsTabOpen)}/>
- <DocCreatorMenuButton icon={'arrow-rotate-backward'} function={() => { this._props.menu.setExpandedView(this._props.template); this.forceUpdate(); }}/>
+ <DocCreatorMenuButton icon={'arrow-rotate-backward'} function={() => { this._props.menu.editLastTemplate(); this.forceUpdate(); }}/>
</div>
</div>
</div>
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts
index 1889e4984..232a9cf67 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts
@@ -137,7 +137,34 @@ export class Template {
});
}
- this._mainField.makeBackgroundField(field)
+ this._mainField.makeBackgroundField(field);
+ }
+
+ /**
+ * This function is just a hack for now to get around weird document icon stuff (specifically it misses the background)
+ */
+ setMatteBackground(makeTransparent: boolean = false) {
+ if (this._mainField.hasBackground) {
+ return;
+ }
+
+ const fieldSettings: FieldSettings = {
+ tl: [-1, -1],
+ br: [1, 1],
+ opts: {backgroundColor: String(this._mainField.renderedDoc!.backgroundColor)},
+ viewType: ViewType.TEXT,
+ }
+
+ const field: TemplateField = TemplateField.CreateField(fieldSettings, Math.random() * 100 + 100, this._mainField);
+
+ if (makeTransparent) {
+ this.allFields.forEach(field => {
+ field.updateDocSetting('backgroundColor', 'transparent');
+ field.updateDocSetting('borderWidth', '0');
+ });
+ }
+
+ this._mainField.makeBackgroundField(field);
}
getMatches = (cols: Col[]): number[][] => {
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts
index fc520ba47..1576dd240 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/DynamicField.ts
@@ -20,6 +20,10 @@ export class DynamicField extends TemplateField {
return this.getSubfields.flatMap(field => [field, ...((field as DynamicField).getAllSubfields ?? [])]);
}
+ get hasBackground() {
+ return this.backgroundField !== undefined;
+ }
+
handleFieldUpdate = (newDocsList: Doc[]) => {
const currRenderedDocs = new Set(this.getSubfields.filter(field => field.renderedDoc).map(field => field.renderedDoc!));
newDocsList.forEach(doc => !currRenderedDocs.has(doc) && this.addFieldFromDoc(doc));
@@ -44,7 +48,10 @@ export class DynamicField extends TemplateField {
addField = (field: TemplateField, layer: number = 0) => {
if (!this._subfields.includes(field)) {
+ console.log('success')
+ console.log('subs: ', this._subfields)
this._subfields.splice(layer, 0, field);
+ console.log('subffelds: ', this._subfields)
}
};
@@ -91,6 +98,7 @@ export class DynamicField extends TemplateField {
const dynClone = super.makeClone(parent) as DynamicField;
dynClone._subfields = this.getSubfields.map(field => {
if (field === this.backgroundField) {
+ console.log('background found')
const backgroundField: TemplateField = field.makeClone(dynClone, true);
dynClone.makeBackgroundField(backgroundField);
return backgroundField;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts
index 2c304247d..a1107caf3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/TemplateFieldTypes/TemplateField.ts
@@ -81,6 +81,11 @@ export abstract class TemplateField {
makeClone(parent?: TemplateField, withContent: boolean = false) {
const settings: FieldSettings = structuredClone(this._settings);
const cloned = TemplateField.CreateField(settings, this._id, parent, true); // create a value for this.Document/subfields that we want to ignore
+ cloned.renderedDoc!.width = this.renderedDoc!.width;
+ cloned.renderedDoc!.height = this.renderedDoc!.height;
+ cloned.renderedDoc!.x = this.renderedDoc!.x;
+ cloned.renderedDoc!.y = this.renderedDoc!.y;
+ cloned.renderedDoc!.backgroundColor = this.renderedDoc!.backgroundColor;
cloned.setTitle(this._title);
cloned._dimensions = this._dimensions;
withContent && cloned.setContent(this.getContent());
@@ -134,6 +139,7 @@ export abstract class TemplateField {
opts._nativeWidth ??= dimensions.width;
opts._nativeHeight ??= dimensions.height;
opts._layout_nativeDimEditable ??= true;
+ opts.layout_boxShadow = 'none';
};
}
diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx
index 73a47681a..8918d1b0e 100644
--- a/src/client/views/smartdraw/DrawingFillHandler.tsx
+++ b/src/client/views/smartdraw/DrawingFillHandler.tsx
@@ -26,11 +26,11 @@ export class DrawingFillHandler {
: Doc.Links(drawing)
.map(link => Doc.getOppositeAnchor(link, drawing))
.map(anchor => anchor && DocCast(anchor.embedContainer));
- const styyleUrl = await DocumentView.GetDocImage(styleDocs.lastElement())?.then(styleImg => {
+ const styleUrl = await DocumentView.GetDocImage(styleDocs.lastElement())?.then(styleImg => {
const hrefParts = ImageCast(styleImg).url.href.split('.');
return `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`;
});
- return DocumentView.GetDocImage(drawing)?.then(imageField => {
+ return DocumentView.GetDocImage(drawing)?.then((imageField) => {
if (imageField) {
const aspectRatio = (drawing.width as number) / (drawing.height as number);
const dims = (() => {
@@ -42,7 +42,7 @@ export class DrawingFillHandler {
const { href } = ImageCast(imageField).url;
const hrefParts = href.split('.');
const structureUrl = `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`;
- const styleUrl = styleDoc ? `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}` : undefined;
+ const styleUrl = `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`;
return imageUrlToBase64(structureUrl)
.then(gptDescribeImage)
.then((prompt, newPrompt = user_prompt || prompt) =>