From 011910a08c25a05d5b925dccd3cad5f27e19bdc1 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:11:55 +1100 Subject: [PATCH] refactor(ui): continued reorg of components & hooks --- .../listeners/workflowLoadRequested.ts | 2 +- .../features/nodes/components/flow/Flow.tsx | 6 +- .../flow/nodes/Invocation/InvocationNode.tsx | 12 +-- .../nodes/Invocation/InvocationNodeFooter.tsx | 4 +- ...ea.tsx => InvocationNodeNotesTextarea.tsx} | 20 ++--- .../InvocationNodeStatusIndicator.tsx | 4 +- .../Invocation/SaveToGalleryCheckbox.tsx | 6 +- .../nodes/Invocation/UseCacheCheckbox.tsx | 2 +- .../fields/FieldResetToDefaultValueButton.tsx | 16 ---- ...eldResetToInitialLinearViewValueButton.tsx | 16 ---- .../fields/FieldResetValueButton.tsx | 25 ------ .../Invocation/fields/FieldTooltipContent.tsx | 63 -------------- ...putFieldAddRemoveLinearViewIconButton.tsx} | 19 ++--- ...inear.tsx => InputFieldEditModeLinear.tsx} | 33 +++----- ...wNodes.tsx => InputFieldEditModeNodes.tsx} | 55 ++++++------ .../Invocation/fields/InputFieldGate.tsx | 8 +- ... InputFieldLinearViewConfigIconButton.tsx} | 12 +-- ...tton.tsx => InputFieldNotesIconButton.tsx} | 8 +- .../Invocation/fields/InputFieldRenderer.tsx | 19 ++--- ...nputFieldResetToDefaultValueIconButton.tsx | 30 +++++++ ...nputFieldResetToInitialValueIconButton.tsx | 30 +++++++ ...ableFieldTitle.tsx => InputFieldTitle.tsx} | 84 +++++++++---------- .../Invocation/fields/InputFieldTooltip.tsx | 49 +++++++++++ .../fields/InputFieldUnknownPlaceholder.tsx | 6 +- .../Invocation/fields/InputFieldViewMode.tsx | 31 +++++++ .../fields/InputFieldViewSimple.tsx | 31 ------- .../Invocation/fields/InputFieldWrapper.tsx | 15 +--- .../Invocation/fields/OutputFieldGate.tsx | 4 +- .../fields/OutputFieldNodesEditorView.tsx | 37 ++++---- .../Invocation/fields/OutputFieldTitle.tsx | 43 ++++++++++ .../Invocation/fields/OutputFieldTooltip.tsx | 29 +++++++ .../fields/OutputFieldUnknownPlaceholder.tsx | 6 +- .../Invocation/fields/OutputFieldWrapper.tsx | 13 +-- .../ImageFieldCollectionInputComponent.tsx | 4 +- .../NumberFieldCollectionInputComponent.tsx | 4 +- .../StringFieldCollectionInputComponent.tsx | 4 +- .../flow/nodes/common/NodeWrapper.tsx | 4 +- ...ntent.tsx => EditModeLeftPanelContent.tsx} | 4 +- .../sidePanel/WorkflowsTabLeftPanel.tsx | 8 +- .../inspector/InspectorDetailsTab.tsx | 6 +- .../inspector/InspectorOutputsTab.tsx | 4 +- ...ntent.tsx => ViewModeLeftPanelContent.tsx} | 14 ++-- .../sidePanel/workflow/WorkflowLinearTab.tsx | 4 +- .../features/nodes/hooks/useBatchGroupId.ts | 27 +++--- .../nodes/hooks/useConnectionState.ts | 59 ------------- .../features/nodes/hooks/useFieldTemplate.ts | 36 -------- .../nodes/hooks/useFieldTemplateTitle.ts | 8 -- .../hooks/useInputFieldConnectionState.ts | 35 ++++++++ ...tValue.ts => useInputFieldDefaultValue.ts} | 10 +-- ...=> useInputFieldInitialLinearViewValue.ts} | 6 +- ...utInstance.ts => useInputFieldInstance.ts} | 11 ++- ...ists.ts => useInputFieldInstanceExists.ts} | 2 +- .../nodes/hooks/useInputFieldIsConnected.ts | 21 +++++ ...IsExposed.ts => useInputFieldIsExposed.ts} | 2 +- ...IsInvalid.ts => useInputFieldIsInvalid.ts} | 16 ++-- ...useFieldLabel.ts => useInputFieldLabel.ts} | 2 +- ...ig.ts => useInputFieldLinearViewConfig.ts} | 2 +- ...FieldInputName.ts => useInputFieldName.ts} | 2 +- ...Names.ts => useInputFieldNamesByStatus.ts} | 2 +- ...useFieldNotes.ts => useInputFieldNotes.ts} | 2 +- ...utTemplate.ts => useInputFieldTemplate.ts} | 2 +- ...ists.ts => useInputFieldTemplateExists.ts} | 2 +- .../nodes/hooks/useInputFieldTemplateTitle.ts | 15 ++++ ...useFieldValue.ts => useInputFieldValue.ts} | 2 +- .../{useCopyPaste.ts => useNodeCopyPaste.ts} | 2 +- ...utionState.ts => useNodeExecutionState.ts} | 2 +- ...mageOutput.ts => useNodeHasImageOutput.ts} | 2 +- .../nodes/hooks/useNodeIsInvocationNode.ts | 20 +++++ .../src/features/nodes/hooks/useNodeNotes.ts | 22 +++++ .../hooks/useOutputFieldConnectionState.ts | 35 ++++++++ .../nodes/hooks/useOutputFieldIsConnected.ts | 21 +++++ ...eldOutputName.ts => useOutputFieldName.ts} | 2 +- ...tTemplate.ts => useOutputFieldTemplate.ts} | 2 +- ...sts.ts => useOutputFieldTemplateExists.ts} | 2 +- .../nodes/hooks/usePrettyFieldType.ts | 5 +- .../src/features/nodes/hooks/useWithFooter.ts | 4 +- .../services/events/onInvocationComplete.tsx | 2 +- .../src/services/events/setEventListeners.tsx | 2 +- 78 files changed, 634 insertions(+), 547 deletions(-) rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/{NotesTextarea.tsx => InvocationNodeNotesTextarea.tsx} (64%) delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/FieldResetToDefaultValueButton.tsx delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/FieldResetToInitialLinearViewValueButton.tsx delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/FieldResetValueButton.tsx delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/FieldTooltipContent.tsx rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{FieldLinearViewToggle.tsx => InputFieldAddRemoveLinearViewIconButton.tsx} (71%) rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{InputFieldViewLinear.tsx => InputFieldEditModeLinear.tsx} (61%) rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{InputFieldViewNodes.tsx => InputFieldEditModeNodes.tsx} (51%) rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{FieldLinearViewConfigIconButton.tsx => InputFieldLinearViewConfigIconButton.tsx} (81%) rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{FieldNotesIconButton.tsx => InputFieldNotesIconButton.tsx} (86%) create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/InputFieldResetToDefaultValueIconButton.tsx create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/InputFieldResetToInitialValueIconButton.tsx rename invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/{EditableFieldTitle.tsx => InputFieldTitle.tsx} (73%) create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/InputFieldTooltip.tsx create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/InputFieldViewMode.tsx delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/InputFieldViewSimple.tsx create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/OutputFieldTitle.tsx create mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/OutputFieldTooltip.tsx rename invokeai/frontend/web/src/features/nodes/components/sidePanel/{LinearViewLeftPanelContent.tsx => EditModeLeftPanelContent.tsx} (92%) rename invokeai/frontend/web/src/features/nodes/components/sidePanel/viewMode/{SimpleViewLeftPanelContent.tsx => ViewModeLeftPanelContent.tsx} (76%) delete mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useConnectionState.ts delete mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useFieldTemplate.ts delete mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useFieldTemplateTitle.ts create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useInputFieldConnectionState.ts rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldDefaultValue.ts => useInputFieldDefaultValue.ts} (64%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInitialLinearViewValue.ts => useInputFieldInitialLinearViewValue.ts} (83%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInputInstance.ts => useInputFieldInstance.ts} (55%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInputInstanceExists.ts => useInputFieldInstanceExists.ts} (90%) create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useInputFieldIsConnected.ts rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldIsExposed.ts => useInputFieldIsExposed.ts} (87%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldIsInvalid.ts => useInputFieldIsInvalid.ts} (81%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldLabel.ts => useInputFieldLabel.ts} (84%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldLinearViewConfig.ts => useInputFieldLinearViewConfig.ts} (88%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInputName.ts => useInputFieldName.ts} (93%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldNames.ts => useInputFieldNamesByStatus.ts} (95%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldNotes.ts => useInputFieldNotes.ts} (89%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInputTemplate.ts => useInputFieldTemplate.ts} (89%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldInputTemplateExists.ts => useInputFieldTemplateExists.ts} (92%) create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useInputFieldTemplateTitle.ts rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldValue.ts => useInputFieldValue.ts} (90%) rename invokeai/frontend/web/src/features/nodes/hooks/{useCopyPaste.ts => useNodeCopyPaste.ts} (99%) rename invokeai/frontend/web/src/features/nodes/hooks/{useExecutionState.ts => useNodeExecutionState.ts} (97%) rename invokeai/frontend/web/src/features/nodes/hooks/{useHasImageOutput.ts => useNodeHasImageOutput.ts} (89%) create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useNodeIsInvocationNode.ts create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useNodeNotes.ts create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useOutputFieldConnectionState.ts create mode 100644 invokeai/frontend/web/src/features/nodes/hooks/useOutputFieldIsConnected.ts rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldOutputName.ts => useOutputFieldName.ts} (93%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldOutputTemplate.ts => useOutputFieldTemplate.ts} (89%) rename invokeai/frontend/web/src/features/nodes/hooks/{useFieldOutputTemplateExists.ts => useOutputFieldTemplateExists.ts} (92%) diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts index 8d39448ad2..cde399e666 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts @@ -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'; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/Flow.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/Flow.tsx index aaeea376a1..aef01fbdff 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/Flow.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/Flow.tsx @@ -3,9 +3,9 @@ import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector, useAppStore } from 'app/store/storeHooks'; import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus'; import { useConnection } from 'features/nodes/hooks/useConnection'; -import { useCopyPaste } from 'features/nodes/hooks/useCopyPaste'; -import { useSyncExecutionState } from 'features/nodes/hooks/useExecutionState'; import { useIsValidConnection } from 'features/nodes/hooks/useIsValidConnection'; +import { useNodeCopyPaste } from 'features/nodes/hooks/useNodeCopyPaste'; +import { useSyncExecutionState } from 'features/nodes/hooks/useNodeExecutionState'; import { useWorkflowWatcher } from 'features/nodes/hooks/useWorkflowWatcher'; import { $addNodeCmdk, @@ -208,7 +208,7 @@ export const Flow = memo(() => { // #endregion - const { copySelection, pasteSelection, pasteSelectionWithEdges } = useCopyPaste(); + const { copySelection, pasteSelection, pasteSelectionWithEdges } = useNodeCopyPaste(); useRegisteredHotkeys({ id: 'copySelection', diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx index ef98639050..fe3c292ad7 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx @@ -3,12 +3,12 @@ import NodeWrapper from 'features/nodes/components/flow/nodes/common/NodeWrapper import { InputFieldGate } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldGate'; import { OutputFieldGate } from 'features/nodes/components/flow/nodes/Invocation/fields/OutputFieldGate'; import { OutputFieldNodesEditorView } from 'features/nodes/components/flow/nodes/Invocation/fields/OutputFieldNodesEditorView'; -import { useFieldNames } from 'features/nodes/hooks/useFieldNames'; +import { useInputFieldNamesByStatus } from 'features/nodes/hooks/useInputFieldNamesByStatus'; import { useOutputFieldNames } from 'features/nodes/hooks/useOutputFieldNames'; import { useWithFooter } from 'features/nodes/hooks/useWithFooter'; import { memo } from 'react'; -import { InputFieldViewNodes } from './fields/InputFieldViewNodes'; +import { InputFieldEditModeNodes } from './fields/InputFieldEditModeNodes'; import InvocationNodeFooter from './InvocationNodeFooter'; import InvocationNodeHeader from './InvocationNodeHeader'; @@ -21,7 +21,7 @@ type Props = { }; const InvocationNode = ({ nodeId, isOpen, label, type, selected }: Props) => { - const fieldNames = useFieldNames(nodeId); + const fieldNames = useInputFieldNamesByStatus(nodeId); const withFooter = useWithFooter(nodeId); const outputFieldNames = useOutputFieldNames(nodeId); @@ -44,7 +44,7 @@ const InvocationNode = ({ nodeId, isOpen, label, type, selected }: Props) => { {fieldNames.connectionFields.map((fieldName, i) => ( - + ))} @@ -58,12 +58,12 @@ const InvocationNode = ({ nodeId, isOpen, label, type, selected }: Props) => { {fieldNames.anyOrDirectFields.map((fieldName) => ( - + ))} {fieldNames.missingFields.map((fieldName) => ( - + ))} diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx index c1ff625d25..467e2b1bb6 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx @@ -1,6 +1,6 @@ import type { ChakraProps } from '@invoke-ai/ui-library'; import { Flex, FormControlGroup } from '@invoke-ai/ui-library'; -import { useHasImageOutput } from 'features/nodes/hooks/useHasImageOutput'; +import { useNodeHasImageOutput } from 'features/nodes/hooks/useNodeHasImageOutput'; import { DRAG_HANDLE_CLASSNAME } from 'features/nodes/types/constants'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; @@ -15,7 +15,7 @@ type Props = { const props: ChakraProps = { w: 'unset' }; const InvocationNodeFooter = ({ nodeId }: Props) => { - const hasImageOutput = useHasImageOutput(nodeId); + const hasImageOutput = useNodeHasImageOutput(nodeId); const isCacheEnabled = useFeatureStatus('invocationCache'); return ( { +type Props = { + nodeId: string; +}; + +export const InvocationNodeNotesTextarea = memo(({ nodeId }: Props) => { const dispatch = useAppDispatch(); - const node = useNode(nodeId); const { t } = useTranslation(); + const notes = useInvocationNodeNotes(nodeId); const handleNotesChanged = useCallback( (e: ChangeEvent) => { dispatch(nodeNotesChanged({ nodeId, notes: e.target.value })); }, [dispatch, nodeId] ); - if (!isInvocationNode(node)) { - return null; - } return ( {t('nodes.notes')} -