From 6e66ab2ab9b5b6f988230aac83ac712b43ccfe3a Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 11 May 2025 01:30:31 -0400 Subject: working on firefly integration --- .../DocCreatorMenu/Menu/TemplatePreviewGrid.tsx | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx new file mode 100644 index 000000000..fb246a0a0 --- /dev/null +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx @@ -0,0 +1,55 @@ +import { Colors } from "@dash/components/src"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, observable, runInAction } from "mobx"; +import React from "react"; +import ReactLoading from "react-loading"; +import { Doc } from "../../../../../../fields/Doc"; +import { StrCast } from "../../../../../../fields/Types"; +import { ObservableReactComponent } from "../../../../ObservableReactComponent"; +import { Template } from "../Template"; +import { observer } from "mobx-react"; +import { DocCreatorMenu } from "../DocCreatorMenu"; +import { TemplatePreviewBox } from "./TemplatePreviewBox"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; + +export interface SuggestedTemplatesProps { + menu: DocCreatorMenu; + loading?: boolean; + templates: Template[]; + title: string; + optionsButtonOpts?: [string, (...args: any) => any]; + previewBoxLeftButtonOpts?: [string, (...args: any) => any]; + previewBoxRightButtonOpts?: [string, (...args: any) => any]; + setupButtonClick: (e: React.PointerEvent, func: () => void) => void; +} + +@observer +export class TemplatePreviewGrid extends ObservableReactComponent { + + render() { + return ( +
+
+
{this.props.title}
+ {this._props.optionsButtonOpts ? () : null} +
+
+ {this._props.loading ? + (
+ +
) + : this.props.templates.map(template => ( + { this.props.menu.setExpandedView(template); this.forceUpdate(); }]} + rightButtonOpts={["plus", (template: Template) => {}]} + /> + ))} +
+
+ ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 59678e34dad0b6587f28ec642c84f6c6ee06543b Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 11 May 2025 02:08:38 -0400 Subject: firefly templates correctly loading --- .../DocCreatorMenu/Menu/TemplateEditingWindow.tsx | 14 +++++++------- .../DataVizBox/DocCreatorMenu/Menu/TemplatePreviewBox.tsx | 4 ++-- .../DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx') diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx index f34b7efcf..fa84616cc 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx @@ -75,10 +75,11 @@ export class TemplateEditingWindow extends ObservableReactComponent) => {component.forceUpdate();}]} + previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]} />
@@ -93,18 +94,17 @@ export class TemplateEditingWindow extends ObservableReactComponent { const newTemplate: Template = this._props.template.cloneBase(); - newTemplate.setImageAsBackground(url, true); - templates.push(newTemplate); + this._props.menu._variations.push(newTemplate); }); this._loading = false; setTimeout(() => { - console.log('setting') - this._props.menu._variations = templates; + this._variationURLs.forEach((url, i) => { + this._props.menu._variations[i].setImageAsBackground(url, true); + }); this.forceUpdate(); - }, 1000); + }); }) }> diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewBox.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewBox.tsx index a7270e540..e94ddfc15 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewBox.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewBox.tsx @@ -19,8 +19,8 @@ import { ImageCast } from "../../../../../../fields/Types"; export interface TemplatePreviewBoxProps { template: Template; menu: DocCreatorMenu; - leftButtonOpts?: [icon: IconProp, func: (template: Template) => void] - rightButtonOpts?: [icon: IconProp, func: (template: Template) => void] + leftButtonOpts?: [icon: IconProp, func: (...args: any) => void] + rightButtonOpts?: [icon: IconProp, func: (...args: any) => void] } export class TemplatePreviewBox extends ObservableReactComponent { diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx index fb246a0a0..e78109b62 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx @@ -17,9 +17,9 @@ export interface SuggestedTemplatesProps { loading?: boolean; templates: Template[]; title: string; - optionsButtonOpts?: [string, (...args: any) => any]; - previewBoxLeftButtonOpts?: [string, (...args: any) => any]; - previewBoxRightButtonOpts?: [string, (...args: any) => any]; + optionsButtonOpts?: [IconProp, (...args: any) => any]; + previewBoxLeftButtonOpts?: [IconProp, (...args: any) => any]; + previewBoxRightButtonOpts?: [IconProp, (...args: any) => any]; setupButtonClick: (e: React.PointerEvent, func: () => void) => void; } @@ -45,7 +45,7 @@ export class TemplatePreviewGrid extends ObservableReactComponent { this.props.menu.setExpandedView(template); this.forceUpdate(); }]} - rightButtonOpts={["plus", (template: Template) => {}]} + rightButtonOpts={this._props.previewBoxRightButtonOpts} /> ))}
-- cgit v1.2.3-70-g09d2 From e62f51bacace3d91f388202135426445721097cc Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 11 May 2025 16:52:17 -0400 Subject: menubutton component --- src/client/apis/gpt/GPT.ts | 4 +- .../DataVizBox/DocCreatorMenu/DocCreatorMenu.scss | 34 ++++---- .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx | 32 ++------ .../DocCreatorMenu/Menu/DocCreatorMenuButton.tsx | 41 ++++++++++ .../DocCreatorMenu/Menu/TemplateEditingWindow.tsx | 90 +++++++++++----------- .../DocCreatorMenu/Menu/TemplatePreviewGrid.tsx | 8 +- .../nodes/DataVizBox/DocCreatorMenu/Template.ts | 2 +- 7 files changed, 122 insertions(+), 89 deletions(-) create mode 100644 src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/DocCreatorMenuButton.tsx (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index d7b378958..455551f40 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -107,13 +107,13 @@ const callTypeMap: { [type in GPTCallType]: GPTCallOpts } = { prompt: 'You will be given a list of field descriptions for one or more templates in the format {field #0: “description”}{field #1: “description”}{...}, and a list of column descriptions in the format {“title”: “description”}{...}. Your job is to match columns with fields based on their descriptions. Your output should be in the following JSON format: {“template_title”:{“#”: “title”, “#”: “title”, “#”: “title” …}, “template_title”:{“#”: “title”, “#”: “title”, “#”: “title” …}} where “template_title” is the templates title as specified in the description provided, # represents the field # and “title” the title of the column assigned to it. A filled out example might look like {“fivefield2”:{“0”:”Name”, “1”:”Image”, “2”:”Caption”, “3”:”Position”, “4”:”Stats”}, “fivefield3”:{0:”Image”, 1:”Name”, 2:”Caption”, 3:”Stats”, 4:”Position”}. Include one object for each template. IT IS VERY IMPORTANT THAT YOU ONLY INCLUDE TEXT IN THE FORMAT ABOVE, WITH NO ADDITIONS WHATSOEVER. Do not include extraneous ‘#’ characters, ‘column’ for columns, or ‘template’ for templates: ONLY THE TITLES AND NUMBERS. There should never be one column assigned to more than one field (ie. if the “name” column is assigned to field 1, it can’t be assigned to any other fields) . Do this for each template whose fields are described. The descriptions are as follows:', }, vizsum: { - model: 'gpt-4-turbo', + model: 'gpt-4.1', maxTokens: 512, temp: 0.5, prompt: 'Your job is to provide brief descriptions for columns in a dataset based on example rows. Your descriptions should be geared towards how each column’s data might fit together into a visual template. Would they make good titles, main focuses, captions, descriptions, etc. Pay special attention to connections between columns, i.e. is there one column that specifically seems to describe/be related to another more than the rest? You should provide your analysis in JSON format like so: {“col1”:”description”, “col2”:”description”, …}. DO NOT INCLUDE ANY OTHER TEXT, ONLY THE JSON.', }, vizsum2: { - model: 'gpt-4-turbo', + model: 'gpt-4.1', maxTokens: 512, temp: 0.5, prompt: 'Your job is to provide structured information on columns in a dataset based on example rows. You will categorize each column in two ways: by type and size. The size categories are as follows: tiny (one or two words), small (a sentence/multiple words), medium (a few sentences), large (a longer paragraph), and huge (a very long or multiple paragraphs). The type categories are as follows: visual (links/file paths to images, pdfs, maps, or any other visual media type), and text (plain text that isn’t a link/file path). Visual media should be assumed to have size “medium” “large” or “huge”. You will give your responses in JSON format, like so: {“title (of column)”:{“type”:”text”, “size”:”small”}, “title (of column)”:{“type”:”visual”, “size”:”medium”}, …}. DO NOT INCLUDE ANY OTHER TEXT, ONLY THE JSON.', diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss index 9fb973265..2a1a79029 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss @@ -27,7 +27,6 @@ background: whitesmoke; background-color: rgb(50, 50, 50); border-radius: 5px; - border: 1px solid rgb(180, 180, 180); padding: 0px; font-size: 13px; //box-shadow: 3px 3px rgb(29, 29, 31); @@ -35,6 +34,24 @@ &:hover { box-shadow: none; } + + &.no-margin { + margin: 0px; + } + + &.border { + border: 1px solid rgb(180, 180, 180); + } + + &.float-right { + float: right; + margin-left: auto; + } + + &.absolute-right { + position: absolute; + right: 0px; + } &.right{ margin-left: 0px; @@ -403,6 +420,8 @@ margin-left: 5%; background-color: rgb(50, 50, 50); border-radius: 5px; + overflow: hidden; + resize: none; } .docCreatorMenu-variations-tab { @@ -459,19 +478,6 @@ width: 100%; } -.section-reveal-options { - margin-top: 0px; - margin-bottom: 0px; - margin-right: 0px; - margin-left: auto; - border: 0px; - background: none; - - &.float-right { - float: right; - } -} - .docCreatorMenu-templates-displays { display: flex; flex-direction: column; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx index 8a98399b6..2e4b81253 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx @@ -37,6 +37,7 @@ import { StaticContentField } from './TemplateFieldTypes/StaticContentField'; import { TemplateMenuAIUtils } from './Backend/TemplateMenuAIUtils' import { TemplatePreviewGrid } from './Menu/TemplatePreviewGrid'; import { TemplateEditingWindow } from './Menu/TemplateEditingWindow'; +import { DocCreatorMenuButton } from './Menu/DocCreatorMenuButton'; export enum LayoutType { FREEFORM = 'Freeform', @@ -983,9 +984,7 @@ export class DocCreatorMenu extends ObservableReactComponent } }))}> {`${field.title} Field`} - + this.removeField(field)}/>
{ this._collapsedCols.includes(field.title) ? null : <> @@ -1042,26 +1041,16 @@ export class DocCreatorMenu extends ObservableReactComponent return (
- - + + runInAction(() => (this._menuContent = 'templates'))}/>
{this.fieldsInfos.map((field, i) => fieldPanel(field, i))}
); } - @computed get editingView() { - return - } - + @computed get editingView() { return } + get renderSelectedViewType() { switch (this._menuContent) { case 'templates': @@ -1073,14 +1062,11 @@ export class DocCreatorMenu extends ObservableReactComponent menu={this} loading={this._GPTLoading} optionsButtonOpts={['gear', () => (this._menuContent = 'dashboard')]} - setupButtonClick={this.setUpButtonClick} templates={this._suggestedTemplates} />
- +
@@ -1166,9 +1152,7 @@ export class DocCreatorMenu extends ObservableReactComponent {topButton('magnifying-glass', 'options', onOptionsSelected, 'middle')} {topButton('bars', 'saved', onSavedSelected, 'right')} - + {this.renderSelectedViewType} diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/DocCreatorMenuButton.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/DocCreatorMenuButton.tsx new file mode 100644 index 000000000..1d8139d40 --- /dev/null +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/DocCreatorMenuButton.tsx @@ -0,0 +1,41 @@ +import { IconProp } from "@fortawesome/fontawesome-svg-core"; +import { ObservableReactComponent } from "../../../../ObservableReactComponent"; +import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { setupMoveUpEvents, returnFalse } from "../../../../../../ClientUtils"; +import { emptyFunction } from "../../../../../../Utils"; +import { undoable } from "../../../../../util/UndoManager"; +import { observer } from "mobx-react"; + +interface DocCreatorMenuButtonProps { + icon: IconProp; + function: () => any; + styles?: string; +} + +@observer +export class DocCreatorMenuButton extends ObservableReactComponent { + + setupButtonClick = (e: React.PointerEvent, func: (...args: any) => void) => { + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + clickEv.preventDefault(); + func(); + }, 'create docs') + ); + }; + + render() { + + return ( + + ); + } +} \ 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 df6b791c7..0434d0ccb 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplateEditingWindow.tsx @@ -15,11 +15,11 @@ import { TemplateMenuAIUtils } from "../Backend/TemplateMenuAIUtils"; import { ObservableReactComponent } from "../../../../ObservableReactComponent"; import { IDisposer } from "mobx-utils"; import { ImageField } from "../../../../../../fields/URLField"; +import { DocCreatorMenuButton } from "./DocCreatorMenuButton"; interface TemplateEditingWindowProps { menu: DocCreatorMenu; template: Template; - setupButtonClick: (e: React.PointerEvent, func: () => void) => void; } @observer @@ -27,7 +27,8 @@ export class TemplateEditingWindow extends ObservableReactComponent + this.disposers.windowDimensions = reaction(() => this._props.menu._resizing, () => { this.forceUpdate() }, { fireImmediately: true } @@ -43,7 +44,12 @@ export class TemplateEditingWindow extends ObservableReactComponent disposer?.()); + Object.values(this.disposers).forEach(disposer => disposer?.()); + } + + setPromptInputRef: React.LegacyRef = (node) => { + this.promptInput = node; + this.forceUpdate(); } setContainerRef: React.LegacyRef = (node) => { @@ -58,6 +64,24 @@ export class TemplateEditingWindow extends ObservableReactComponent { + this._props.menu._variations = []; + this._loading = true; + this._variationURLs = await this._props.menu.generateVariations(this._props.template.clone(false).getRenderedDoc()!, this.fireflyPrompt); + this._variationURLs.forEach(url => { + const newTemplate: Template = this._props.template.clone(true); + this._props.menu._variations.push(newTemplate); + }); + this._loading = false; + setTimeout(() => { + this._variationURLs.forEach((url, i) => { + this._props.menu._variations[i].setImageAsBackground(url, true); + }); + this.forceUpdate(); + }); } get fireflyVariationsTab() { @@ -71,37 +95,27 @@ export class TemplateEditingWindow extends ObservableReactComponent {}]} - setupButtonClick={this._props.setupButtonClick} previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]} />