Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: workflow builder #7608

Open
wants to merge 125 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
80efe40
feat(ui): add notes state to fields
psychedelicious Jan 17, 2025
98e76ce
feat(ui): add notes popover to field title bar
psychedelicious Jan 17, 2025
f6dad11
feat(ui): show notes icon on editor linear view
psychedelicious Jan 17, 2025
8b6e5df
feat(ui): show notes icon on user-linear view, replacing info icon
psychedelicious Jan 17, 2025
f9a01e1
feat(ui): clean up user-linear view styling
psychedelicious Jan 17, 2025
86a0946
feat(ui): add ViewContext so components can know where they are being…
psychedelicious Jan 17, 2025
0dbb2cc
perf(ui): use data attribute for input field wrapper styles
psychedelicious Jan 19, 2025
380b7ae
refactor(ui): workflows component structure (WIP)
psychedelicious Jan 20, 2025
8c5d598
refactor(ui): workflows left panel internal components structure
psychedelicious Jan 20, 2025
bb78c72
fix(ui): remove accidental change to zFieldInput schema
psychedelicious Jan 20, 2025
32e1823
refactor(ui): continued reorg of components & hooks
psychedelicious Jan 20, 2025
cf77ee5
refactor(ui): continued reorg of components & hooks
psychedelicious Jan 20, 2025
5fbee37
fix(ui): color field component layout
psychedelicious Jan 20, 2025
9f6b0be
feat(ui): get configurable notes display working
psychedelicious Jan 20, 2025
72314d1
feat(ui): use workflows view context
psychedelicious Jan 20, 2025
3947665
fix(ui): dynamic prompts infinite recursion (wip)
psychedelicious Jan 20, 2025
577e8f1
feat(ui): rough out workflow builder data structure & dummy data
psychedelicious Jan 21, 2025
6d548f4
refactor(ui): split up float and integer field renderers
psychedelicious Jan 21, 2025
29b1487
revert(ui): rip out linear view config stuff
psychedelicious Jan 22, 2025
d8ab884
refactor(ui): split integer, float and string field components in pre…
psychedelicious Jan 22, 2025
27cda69
feat(ui): rough out workflow builder data structure
psychedelicious Jan 22, 2025
d0a1960
chore(ui): lint
psychedelicious Jan 22, 2025
3c43e7b
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
a7f0afa
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
8202164
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
e1726f6
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
ed52d0e
feat(ui): getPrefixedId supports custom separator
psychedelicious Jan 22, 2025
79dc992
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
cc5dab7
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
a71220e
feat(ui): iterate on builder (WIP)
psychedelicious Jan 22, 2025
18ba302
feat(ui): iterate on builder (WIP)
psychedelicious Jan 23, 2025
8705ce1
feat(ui): hacking on dnd (WIP)
psychedelicious Jan 23, 2025
01bace2
feat(ui): dim form element while dragging
psychedelicious Jan 23, 2025
27805b9
feat(ui): dnd mostly working (WIP)
psychedelicious Jan 24, 2025
6d6a855
feat(ui): dnd almost fully working (WIP)
psychedelicious Jan 24, 2025
502ad46
feat(ui): improved dnd hitbox for edges when center drop is allowed
psychedelicious Jan 24, 2025
d6bb971
feat(ui): dnd drop target styling
psychedelicious Jan 24, 2025
a6b8410
fix(ui): do not allow reparenting to self
psychedelicious Jan 24, 2025
cf6b2e8
feat(ui): improved drop target styling
psychedelicious Jan 24, 2025
b7696c3
feat(ui): support adding form elements and node fields with dnd
psychedelicious Jan 25, 2025
2624d18
fix(ui): allow root element to be drop target
psychedelicious Jan 25, 2025
b24f215
fix(ui): start workflow w/ single column as root
psychedelicious Jan 25, 2025
84446ff
fix(ui): use redux store for form
psychedelicious Jan 25, 2025
e2d207b
tidy(ui): remove unused mock form builder data
psychedelicious Jan 25, 2025
e47af91
fix(ui): hide nonfunctional delete button on root form element
psychedelicious Jan 25, 2025
09037a4
chore(ui): upgrade reactflow to v12
psychedelicious Jan 25, 2025
b8b5338
refactor(ui): edge rendering
psychedelicious Jan 25, 2025
201ad13
tweak(ui): node selection colors
psychedelicious Jan 25, 2025
2bdab84
fix(ui): do not render dashed edges unless animation is enabled
psychedelicious Jan 25, 2025
d359c9a
fix(ui): node-autoconnect showing invalid connection options
psychedelicious Jan 26, 2025
6e3ee18
chore(ui): lint
psychedelicious Jan 26, 2025
2d1182d
chore(ui): lint
psychedelicious Jan 26, 2025
e64b4cb
perf(ui): faster InputFieldRenderer
psychedelicious Jan 26, 2025
87a5501
fix(ui): circular dep
psychedelicious Jan 26, 2025
cf3e3a8
tidy(ui): import reactflow css in main theme provider
psychedelicious Jan 26, 2025
c858ded
feat(ui): plumbing for editable form elements
psychedelicious Jan 30, 2025
8a512eb
chore(ui): bump @invoke-ai/ui-library
psychedelicious Jan 31, 2025
dbd23ca
feat(ui): editable heading and text elements
psychedelicious Jan 31, 2025
6c5e223
fix(ui): drop indicator getting greyed out when dragging over self
psychedelicious Jan 31, 2025
b97095c
feat(ui): remove sizes from text & heading
psychedelicious Jan 31, 2025
36d4165
refactor(ui): updated component structure for input and output fields
psychedelicious Feb 5, 2025
1365ca4
feat(ui): builder field settings (WIP)
psychedelicious Feb 5, 2025
65b2d42
feat(ui): builder field settings (WIP)
psychedelicious Feb 5, 2025
16951ba
fix(ui): divider layout
psychedelicious Feb 5, 2025
2bc793b
feat(ui): builder field settings (WIP)
psychedelicious Feb 5, 2025
3d6674c
feat(ui): use useEditable in builder
psychedelicious Feb 5, 2025
72eb88c
feat(ui): add float field display settings
psychedelicious Feb 5, 2025
4c67745
feat(ui): editable node form field labels & descriptions
psychedelicious Feb 6, 2025
1ef65a4
fix(ui): tsc issues
psychedelicious Feb 6, 2025
3b3b662
fix(ui): drop target jank
psychedelicious Feb 6, 2025
f349ffe
feat(ui): empty state for drop containers
psychedelicious Feb 6, 2025
53bb24d
feat(ui): builder empty state (WIP)
psychedelicious Feb 6, 2025
7155e01
feat(ui): string field settings
psychedelicious Feb 6, 2025
978b8e5
feat(ui): delete form elements when node is deleted from workflow
psychedelicious Feb 6, 2025
e1db447
feat(ui): iterate on builder data structure
psychedelicious Feb 6, 2025
8f0243f
fix(ui): remove node field from form correctly when node is deleted
psychedelicious Feb 6, 2025
31e13cb
feat(ui): make drop targets that are in root sticky
psychedelicious Feb 6, 2025
ac740ca
feat(ui): builder edit/view buttons
psychedelicious Feb 6, 2025
e6ec2ef
fix(ui): divider rendering
psychedelicious Feb 6, 2025
28dcf9f
refactor(ui): add dispatchAndFlash util for dnd
psychedelicious Feb 6, 2025
6125549
tidy(ui): rename root utils in dnd
psychedelicious Feb 6, 2025
9243835
refactor(ui): clean up dnd logic
psychedelicious Feb 6, 2025
ea98e80
refactor(ui): add vars in dnd logic for conciseness
psychedelicious Feb 6, 2025
5913e76
tidy(ui): dnd logic formatting
psychedelicious Feb 6, 2025
d938583
tidy(ui): improve dnd hook names
psychedelicious Feb 6, 2025
7e75795
tidy(ui): rename builder dnd file
psychedelicious Feb 6, 2025
65c38d1
tidy(ui): dnd code lint
psychedelicious Feb 6, 2025
76235fa
revert(ui): code lint that broke stuff
psychedelicious Feb 7, 2025
3eff4fd
feat(ui): workflow builder layout
psychedelicious Feb 7, 2025
97d648e
feat(ui): be double extra sure migrated workflows are parsed before l…
psychedelicious Feb 7, 2025
dd70334
fix(ui): do not error in node/field selectors are used outside field …
psychedelicious Feb 7, 2025
d26fe1b
feat(ui): migrated linear view exposed fields to builder form on load
psychedelicious Feb 7, 2025
0e5ea31
feat(ui): auto-update nodes on loading workflow
psychedelicious Feb 7, 2025
f18ef00
tidy(ui): node description components
psychedelicious Feb 7, 2025
242df1d
fix(ui): incorrect node data used during update
psychedelicious Feb 7, 2025
dd88142
chore(ui): lint
psychedelicious Feb 7, 2025
3d4ff8a
fix(ui): handle form fields not existing on node on workflow load
psychedelicious Feb 7, 2025
790b5ed
feat(ui): rearrange builder buttons to be less annoying
psychedelicious Feb 7, 2025
0d41722
feat(ui): initial values for form fields (WIP)
psychedelicious Feb 7, 2025
72a4f04
tidy(ui): extract util in dnd
psychedelicious Feb 11, 2025
c694357
tidy(ui): useNodeFieldDnd
psychedelicious Feb 11, 2025
fed74c5
feat(ui): demote dnd logs to trace
psychedelicious Feb 11, 2025
de83670
refactor(ui): remove confusing `containerId` from various builder act…
psychedelicious Feb 11, 2025
4174d61
feat(ui): default form field settings
psychedelicious Feb 11, 2025
a532231
tweak(ui): layout of workflow builder field settings
psychedelicious Feb 11, 2025
01b9918
feat(ui): better placeholders for text/heading
psychedelicious Feb 11, 2025
f33b692
feat(ui): add initial values for builder fields
psychedelicious Feb 11, 2025
166b1ec
feat(ui): remove the showLabel flag for node fields
psychedelicious Feb 11, 2025
a8fcf1d
tidy(ui): builder dnd monitor logic rearrange
psychedelicious Feb 11, 2025
72d0595
fix(ui): ignore dropping on self
psychedelicious Feb 11, 2025
ed7490e
feat(ui): remove node field reset button from edit mode header
psychedelicious Feb 11, 2025
ae73f66
tweak(ui): styling for edit mode
psychedelicious Feb 11, 2025
c41100f
feat(ui): remove element id from edit mode header
psychedelicious Feb 11, 2025
41cef71
feat(ui): text and heading element default content is empty string
psychedelicious Feb 11, 2025
6be877b
feat(ui): remove separate flag for form vs workflow edit mode
psychedelicious Feb 11, 2025
8e4ef2b
feat(ui): consolidate row/column dnd draggables into container
psychedelicious Feb 11, 2025
5b93a3f
tweak(ui): builder padding
psychedelicious Feb 11, 2025
e7dfd50
tidy(ui): remove nonfunctional conditionals
psychedelicious Feb 11, 2025
c72dbf8
fix(ui): remove images from node image collections when deleted
psychedelicious Feb 11, 2025
5c36c58
feat(ui): add delete button to missing image placeholder for image co…
psychedelicious Feb 11, 2025
7f99169
fix(ui): force refetch when checking image access to ensure stale RTK…
psychedelicious Feb 11, 2025
b4b7054
feat(ui): check image access for image collections when loading workf…
psychedelicious Feb 11, 2025
8eee9ea
feat(ui): add warning about alpha status of builder
psychedelicious Feb 11, 2025
34cc389
tweak(ui): form element edit mode styling
psychedelicious Feb 11, 2025
3d13365
feat(ui): give vertical dividers a min height
psychedelicious Feb 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions invokeai/frontend/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@
"@dagrejs/dagre": "^1.1.4",
"@dagrejs/graphlib": "^2.2.4",
"@fontsource-variable/inter": "^5.1.0",
"@invoke-ai/ui-library": "^0.0.44",
"@invoke-ai/ui-library": "^0.0.46",
"@nanostores/react": "^0.7.3",
"@reduxjs/toolkit": "2.2.3",
"@roarr/browser-log-writer": "^1.3.0",
"@xyflow/react": "^12.4.2",
"async-mutex": "^0.5.0",
"chakra-react-select": "^4.9.2",
"cmdk": "^1.0.0",
Expand Down Expand Up @@ -96,9 +97,9 @@
"react-icons": "^5.3.0",
"react-redux": "9.1.2",
"react-resizable-panels": "^2.1.4",
"react-textarea-autosize": "^8.5.7",
"react-use": "^17.5.1",
"react-virtuoso": "^4.10.4",
"reactflow": "^11.11.4",
"redux-dynamic-middlewares": "^2.2.0",
"redux-remember": "^5.1.0",
"redux-undo": "^1.1.0",
Expand Down
590 changes: 267 additions & 323 deletions invokeai/frontend/web/pnpm-lock.yaml

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions invokeai/frontend/web/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,10 @@
"values": "Values",
"resetToDefaults": "Reset to Defaults",
"seed": "Seed",
"combinatorial": "Combinatorial"
"combinatorial": "Combinatorial",
"layout": "Layout",
"row": "Row",
"column": "Column"
},
"hrf": {
"hrf": "High Resolution Fix",
Expand Down Expand Up @@ -931,13 +934,15 @@
"noWorkflows": "No Workflows",
"noMatchingWorkflows": "No Matching Workflows",
"noWorkflow": "No Workflow",
"unableToUpdateNode": "Node update failed: node {{node}} of type {{type}} (may require deleting and recreating)",
"mismatchedVersion": "Invalid node: node {{node}} of type {{type}} has mismatched version (try updating?)",
"missingTemplate": "Invalid node: node {{node}} of type {{type}} missing template (not installed?)",
"sourceNodeDoesNotExist": "Invalid edge: source/output node {{node}} does not exist",
"targetNodeDoesNotExist": "Invalid edge: target/input node {{node}} does not exist",
"sourceNodeFieldDoesNotExist": "Invalid edge: source/output field {{node}}.{{field}} does not exist",
"targetNodeFieldDoesNotExist": "Invalid edge: target/input field {{node}}.{{field}} does not exist",
"deletedInvalidEdge": "Deleted invalid edge {{source}} -> {{target}}",
"deletedMissingNodeFieldFormElement": "Deleted missing form field: node {{nodeId}} field {{fieldName}}",
"noConnectionInProgress": "No connection in progress",
"node": "Node",
"nodeOutputs": "Node Outputs",
Expand All @@ -952,6 +957,7 @@
"nodeVersion": "Node Version",
"noOutputRecorded": "No outputs recorded",
"notes": "Notes",
"description": "Description",
"notesDescription": "Add notes about your workflow",
"problemSettingTitle": "Problem Setting Title",
"resetToDefaultValue": "Reset to default value",
Expand Down Expand Up @@ -1694,7 +1700,26 @@
"download": "Download",
"copyShareLink": "Copy Share Link",
"copyShareLinkForWorkflow": "Copy Share Link for Workflow",
"delete": "Delete"
"delete": "Delete",
"builder": {
"builder": "Builder",
"layout": "Layout",
"row": "Row",
"column": "Column",
"label": "Label",
"description": "Description",
"component": "Component",
"numberInput": "Number Input",
"slider": "Slider",
"both": "Both",
"emptyRootPlaceholderViewMode": "Click Edit to start building a form for this workflow.",
"emptyRootPlaceholderEditMode": "Drag a form element or node field here to get started.",
"containerPlaceholder": "Empty Container",
"containerPlaceholderDesc": "Drag a form element or node field into this container.",
"headingPlaceholder": "Empty Heading",
"textPlaceholder": "Empty Text",
"workflowBuilderAlphaWarning": "The workflow builder is currently in alpha. There may be breaking changes before the stable release."
}
},
"controlLayers": {
"regional": "Regional",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@fontsource-variable/inter';
import 'overlayscrollbars/overlayscrollbars.css';
import '@xyflow/react/dist/base.css';

import { ChakraProvider, DarkMode, extendTheme, theme as _theme, TOAST_OPTIONS } from '@invoke-ai/ui-library';
import type { ReactNode } from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,50 @@ import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions'
import { isModalOpenChanged } from 'features/deleteImageModal/store/slice';
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';
import { imageSelected } from 'features/gallery/store/gallerySlice';
import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
import { isImageFieldInputInstance } from 'features/nodes/types/field';
import { fieldImageCollectionValueChanged, fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
import { isImageFieldCollectionInputInstance, isImageFieldInputInstance } from 'features/nodes/types/field';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { forEach, intersectionBy } from 'lodash-es';
import { imagesApi } from 'services/api/endpoints/images';
import type { ImageDTO } from 'services/api/types';
import type { Param0 } from 'tsafe';

const log = logger('gallery');

//TODO(psyche): handle image deletion (canvas staging area?)

// Some utils to delete images from different parts of the app
const deleteNodesImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
const actions: Param0<typeof dispatch>[] = [];
state.nodes.present.nodes.forEach((node) => {
if (!isInvocationNode(node)) {
return;
}

forEach(node.data.inputs, (input) => {
if (isImageFieldInputInstance(input) && input.value?.image_name === imageDTO.image_name) {
dispatch(
actions.push(
fieldImageValueChanged({
nodeId: node.data.id,
fieldName: input.name,
value: undefined,
})
);
return;
}
if (isImageFieldCollectionInputInstance(input)) {
actions.push(
fieldImageCollectionValueChanged({
nodeId: node.data.id,
fieldName: input.name,
value: input.value?.filter((value) => value?.image_name !== imageDTO.image_name),
})
);
}
});
});

actions.forEach(dispatch);
};

const deleteControlLayerImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { $nodeExecutionStates } from 'features/nodes/hooks/useExecutionState';
import { $nodeExecutionStates } from 'features/nodes/hooks/useNodeExecutionState';
import { workflowLoaded, workflowLoadRequested } from 'features/nodes/store/actions';
import { $templates } from 'features/nodes/store/nodesSlice';
import { $needsFit } from 'features/nodes/store/reactFlowInstance';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { As, ChakraProps, FlexProps } from '@invoke-ai/ui-library';
import type { ChakraProps, FlexProps } from '@invoke-ai/ui-library';
import { Flex, Icon, Skeleton, Spinner, Text } from '@invoke-ai/ui-library';
import type { ElementType } from 'react';
import { memo, useMemo } from 'react';
import { PiImageBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types';
Expand Down Expand Up @@ -28,7 +29,7 @@ IAILoadingImageFallback.displayName = 'IAILoadingImageFallback';

type IAINoImageFallbackProps = FlexProps & {
label?: string;
icon?: As | null;
icon?: ElementType | null;
boxSize?: ChakraProps['boxSize'];
};

Expand Down

This file was deleted.

Loading
Loading