diff options
| author | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2025-05-11 16:52:17 -0400 |
|---|---|---|
| committer | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2025-05-11 16:52:17 -0400 |
| commit | e62f51bacace3d91f388202135426445721097cc (patch) | |
| tree | 0b652d55e6c055b63c43feba7a41d1bab28af005 /src/client/views/nodes/DataVizBox/DocCreatorMenu | |
| parent | 4af498433a887c70dc7043a5a34eef7fff5bbbe0 (diff) | |
menubutton component
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu')
6 files changed, 120 insertions, 87 deletions
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<DocCreateMenuProps> } }))}> <span className="field-title">{`${field.title} Field`}</span> - <button className="docCreatorMenu-menu-button section-reveal-options no-margin" onPointerDown={e => this.setUpButtonClick(e, () => this.removeField(field))} style={{ position: 'absolute', right: '0px' }}> - <FontAwesomeIcon icon="minus" /> - </button> + <DocCreatorMenuButton icon={'minus'} styles={'no-margin absolute-right'} function={() => this.removeField(field)}/> </div> { this._collapsedCols.includes(field.title) ? null : <> @@ -1042,26 +1041,16 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps> 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> + <DocCreatorMenuButton icon={'plus'} function={this.addField}/> + <DocCreatorMenuButton icon={'arrow-left'} styles={'float-right'} function={() => runInAction(() => (this._menuContent = 'templates'))}/> </div> <div className="panels-container">{this.fieldsInfos.map((field, i) => fieldPanel(field, i))}</div> </div> ); } - @computed get editingView() { - return <TemplateEditingWindow - setupButtonClick={this.setUpButtonClick} - template={this._currEditingTemplate as Template} - menu={this} - /> - } - + @computed get editingView() { return <TemplateEditingWindow template={this._currEditingTemplate as Template} menu={this} /> } + get renderSelectedViewType() { switch (this._menuContent) { case 'templates': @@ -1073,14 +1062,11 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps> menu={this} loading={this._GPTLoading} optionsButtonOpts={['gear', () => (this._menuContent = 'dashboard')]} - setupButtonClick={this.setUpButtonClick} templates={this._suggestedTemplates} /> <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> + <DocCreatorMenuButton icon={'arrows-rotate'} styles={'border'} function={this.generatePresetTemplates}/> </div> </div> </div> @@ -1166,9 +1152,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps> {topButton('magnifying-glass', 'options', onOptionsSelected, 'middle')} {topButton('bars', 'saved', onSavedSelected, 'right')} </div> - <button className="docCreatorMenu-menu-button close-menu" onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}> - <FontAwesomeIcon icon="minus" /> - </button> + <DocCreatorMenuButton icon={'minus'} styles={'float-right'} function={this.closeMenu}/> </div> {this.renderSelectedViewType} </div> 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<DocCreatorMenuButtonProps> { + + setupButtonClick = (e: React.PointerEvent, func: (...args: any) => void) => { + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + clickEv.preventDefault(); + func(); + }, 'create docs') + ); + }; + + render() { + + return ( + <button className={`docCreatorMenu-menu-button ${this._props.styles}`} onPointerDown={e => this.setupButtonClick(e, async () => this._props.function())}> + <FontAwesomeIcon icon={this._props.icon} /> + </button> + ); + } +}
\ 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<TemplateEdit private fireflyPrompt: string = 'Use this template to generate an empty baseball card template.'; private previewWindow: HTMLDivElement | null = null; - private _disposers: { [name: string]: IDisposer } = {}; + private disposers: { [name: string]: IDisposer } = {}; + private promptInput: HTMLTextAreaElement | null = null; @observable _loading: boolean = false; @observable _variationsTabOpen: boolean = false; @@ -35,7 +36,7 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit @observable _variations: Template[] = []; componentDidMount(): void { - this._disposers.windowDimensions = reaction(() => + this.disposers.windowDimensions = reaction(() => this._props.menu._resizing, () => { this.forceUpdate() }, { fireImmediately: true } @@ -43,7 +44,12 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit } componentWillUnmount() { - Object.values(this._disposers).forEach(disposer => disposer?.()); + Object.values(this.disposers).forEach(disposer => disposer?.()); + } + + setPromptInputRef: React.LegacyRef<HTMLTextAreaElement> = (node) => { + this.promptInput = node; + this.forceUpdate(); } setContainerRef: React.LegacyRef<HTMLDivElement> = (node) => { @@ -58,6 +64,24 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit } else if (this.previewWindow && !open) { this.previewWindow.style.height = String(Number(this.previewWindow.clientHeight) * 5/3); } + this.forceUpdate(); + } + + generateVariations = async () => { + 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<TemplateEdit loading={this._loading} templates={this._props.menu._variations} optionsButtonOpts={['gear', () => {}]} - setupButtonClick={this._props.setupButtonClick} previewBoxRightButtonOpts={['gear', (template: Template) => {this.forceUpdate();}]} /> <div className="docCreatorMenu-section"> <div className="docCreatorMenu-variation-prompt-input"> <textarea className="docCreatorMenu-variation-prompt-input-textbox" + ref={this.setPromptInputRef} onChange={e => this.fireflyPrompt = e.target.value} + onInput={() => { + if (this.promptInput !== null) { + this.promptInput.style.height = 'auto'; + this.promptInput.style.height = this.promptInput.scrollHeight + 'px'; + } + }} defaultValue={''} placeholder={'Enter a custom prompt here (optional)'} /> - <button className="docCreatorMenu-menu-button" - onPointerDown={e => this._props.setupButtonClick(e, async () => { - 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(); - }); - }) - }> - <FontAwesomeIcon icon="arrows-rotate" /> - </button> + <DocCreatorMenuButton icon={'arrows-rotate'} styles={'border'} function={this.generateVariations}/> + </div> + <div className='docCreatorMenu-variation-options-container'> + </div> </div> </> @@ -146,25 +160,13 @@ export class TemplateEditingWindow extends ObservableReactComponent<TemplateEdit {this.renderedDocPreview} {this._variationsTabOpen ? this.fireflyVariationsTab : null} <div className="right-buttons-panel"> - <button - className="docCreatorMenu-menu-button section-reveal-options top-right" - onPointerDown={e => - this._props.setupButtonClick(e, () => { - if (this._props.template === this._props.menu._selectedTemplate) { - this._props.menu.updateRenderedPreviewCollection(this._props.template); - } - this._props.menu.setExpandedView(undefined); - }) - }> - <FontAwesomeIcon icon="minimize" /> - </button> - <button className="docCreatorMenu-menu-button section-reveal-options top-right" onPointerDown={e => this._props.setupButtonClick(e, async () => { - this.setVariationTab(!this._variationsTabOpen); - // this._props.template.setImageAsBackground('https://www.onthegotours.com/repository/Great-Wall-New-Pic-228551391689622.jpg', true); - this.forceUpdate(); - })}> - <FontAwesomeIcon icon="lightbulb" /> - </button> + <DocCreatorMenuButton icon={'minimize'} function={() => { + if (this._props.template === this._props.menu._selectedTemplate) { + this._props.menu.updateRenderedPreviewCollection(this._props.template); + } + this._props.menu.setExpandedView(undefined); + }}/> + <DocCreatorMenuButton icon={'lightbulb'} function={() => this.setVariationTab(!this._variationsTabOpen)}/> </div> </div> </div> diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx index e78109b62..84ca6546d 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Menu/TemplatePreviewGrid.tsx @@ -11,6 +11,7 @@ import { observer } from "mobx-react"; import { DocCreatorMenu } from "../DocCreatorMenu"; import { TemplatePreviewBox } from "./TemplatePreviewBox"; import { IconProp } from "@fortawesome/fontawesome-svg-core"; +import { DocCreatorMenuButton } from "./DocCreatorMenuButton"; export interface SuggestedTemplatesProps { menu: DocCreatorMenu; @@ -20,7 +21,6 @@ export interface SuggestedTemplatesProps { optionsButtonOpts?: [IconProp, (...args: any) => any]; previewBoxLeftButtonOpts?: [IconProp, (...args: any) => any]; previewBoxRightButtonOpts?: [IconProp, (...args: any) => any]; - setupButtonClick: (e: React.PointerEvent, func: () => void) => void; } @observer @@ -31,9 +31,9 @@ export class TemplatePreviewGrid extends ObservableReactComponent<SuggestedTempl <div className="docCreatorMenu-section"> <div className="docCreatorMenu-section-topbar"> <div className="docCreatorMenu-section-title">{this.props.title}</div> - {this._props.optionsButtonOpts ? (<button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.props.setupButtonClick(e, () => runInAction(this._props.optionsButtonOpts![1]))}> - <FontAwesomeIcon icon={this._props.optionsButtonOpts[0] as IconProp} /> - </button>) : null} + {this._props.optionsButtonOpts ? + <DocCreatorMenuButton icon={this._props.optionsButtonOpts[0] as IconProp} styles={'float-right'} function={() => runInAction(this._props.optionsButtonOpts![1])}/> + : null} </div> <div className="docCreatorMenu-templates-preview-window"> {this._props.loading ? diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts index 10724c9f7..7ff521f18 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.ts @@ -81,7 +81,7 @@ export class Template { isValidTemplate = (cols: Col[]) => { const maxMatches = this.maxMatches(this.getMatches(cols)); - return maxMatches === this.contentFields.length; + return maxMatches === this.contentFields.length && this.title !== 'template_framework'; }; applyConditionalLogicToField = (field: TemplateField) => { |
