fix(ui): do not use state => state as an input selector

This is a no-no, whoops!
This commit is contained in:
psychedelicious
2024-01-05 19:44:22 +11:00
parent ce64dbefce
commit a23502f7ff
235 changed files with 1087 additions and 951 deletions

View File

@ -39,7 +39,7 @@ const exit: AnimationProps['exit'] = {
};
const NodeEditor = () => {
const isReady = useAppSelector((state) => state.nodes.isReady);
const isReady = useAppSelector((s) => s.nodes.isReady);
const { t } = useTranslation();
return (
<Flex

View File

@ -3,7 +3,6 @@ import 'reactflow/dist/style.css';
import { Flex } from '@chakra-ui/react';
import { useAppToaster } from 'app/components/Toaster';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import type { SelectInstance } from 'chakra-react-select';
import {
@ -21,8 +20,8 @@ import { useBuildNode } from 'features/nodes/hooks/useBuildNode';
import {
addNodePopoverClosed,
addNodePopoverOpened,
nodeAdded,
} from 'features/nodes/store/nodesSlice';
nodeAdded } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { validateSourceAndTargetTypes } from 'features/nodes/store/util/validateSourceAndTargetTypes';
import { filter, map, memoize, some } from 'lodash-es';
import type { KeyboardEventHandler } from 'react';
@ -68,15 +67,15 @@ const AddNodePopover = () => {
const inputRef = useRef<HTMLInputElement>(null);
const fieldFilter = useAppSelector(
(state) => state.nodes.connectionStartFieldType
(s) => s.nodes.connectionStartFieldType
);
const handleFilter = useAppSelector(
(state) => state.nodes.connectionStartParams?.handleType
(s) => s.nodes.connectionStartParams?.handleType
);
const selector = createMemoizedSelector(
[stateSelector],
({ nodeTemplates }) => {
selectNodeTemplatesSlice,
(nodeTemplates) => {
// If we have a connection in progress, we need to filter the node choices
const filteredNodeTemplates = fieldFilter
? filter(nodeTemplates.templates, (template) => {
@ -130,7 +129,7 @@ const AddNodePopover = () => {
);
const { options } = useAppSelector(selector);
const isOpen = useAppSelector((state) => state.nodes.isAddNodePopoverOpen);
const isOpen = useAppSelector((s) => s.nodes.isAddNodePopoverOpen);
const addNode = useCallback(
(nodeType: string) => {

View File

@ -71,13 +71,13 @@ const snapGrid: [number, number] = [25, 25];
export const Flow = memo(() => {
const dispatch = useAppDispatch();
const nodes = useAppSelector((state) => state.nodes.nodes);
const edges = useAppSelector((state) => state.nodes.edges);
const viewport = useAppSelector((state) => state.nodes.viewport);
const nodes = useAppSelector((s) => s.nodes.nodes);
const edges = useAppSelector((s) => s.nodes.edges);
const viewport = useAppSelector((s) => s.nodes.viewport);
const shouldSnapToGrid = useAppSelector(
(state) => state.nodes.shouldSnapToGrid
(s) => s.nodes.shouldSnapToGrid
);
const selectionMode = useAppSelector((state) => state.nodes.selectionMode);
const selectionMode = useAppSelector((s) => s.nodes.selectionMode);
const flowWrapper = useRef<HTMLDivElement>(null);
const cursorPosition = useRef<XYPosition | null>(null);
const isValidConnection = useIsValidConnection();

View File

@ -1,14 +1,14 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { colorTokenToCssVar } from 'common/util/colorTokenToCssVar';
import { getFieldColor } from 'features/nodes/components/flow/edges/util/getEdgeColor';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import type { CSSProperties } from 'react';
import { memo } from 'react';
import type { ConnectionLineComponentProps } from 'reactflow';
import { getBezierPath } from 'reactflow';
const selector = createMemoizedSelector(stateSelector, ({ nodes }) => {
const selector = createMemoizedSelector(selectNodesSlice, (nodes) => {
const { shouldAnimateEdges, connectionStartFieldType, shouldColorEdges } =
nodes;

View File

@ -1,6 +1,6 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { colorTokenToCssVar } from 'common/util/colorTokenToCssVar';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getFieldColor } from './getEdgeColor';
@ -12,7 +12,7 @@ export const makeEdgeSelector = (
targetHandleId: string | null | undefined,
selected?: boolean
) =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const sourceNode = nodes.nodes.find((node) => node.id === source);
const targetNode = nodes.nodes.find((node) => node.id === target);

View File

@ -1,13 +1,14 @@
import { Flex, Image } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import IAIDndImage from 'common/components/IAIDndImage';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { InvText } from 'common/components/InvText/wrapper';
import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
import { selectGallerySlice } from 'features/gallery/store/gallerySlice';
import NodeWrapper from 'features/nodes/components/flow/nodes/common/NodeWrapper';
import { DRAG_HANDLE_CLASSNAME } from 'features/nodes/types/constants';
import { selectSystemSlice } from 'features/system/store/systemSlice';
import type { AnimationProps } from 'framer-motion';
import { motion } from 'framer-motion';
import type { CSSProperties, PropsWithChildren } from 'react';
@ -16,8 +17,9 @@ import { useTranslation } from 'react-i18next';
import type { NodeProps } from 'reactflow';
const selector = createMemoizedSelector(
stateSelector,
({ system, gallery }) => {
selectSystemSlice,
selectGallerySlice,
(system, gallery) => {
const imageDTO = gallery.selection[gallery.selection.length - 1];
return {

View File

@ -1,10 +1,10 @@
import type { SystemStyleObject } from '@chakra-ui/react';
import { Badge, CircularProgress, Flex, Icon, Image } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { InvText } from 'common/components/InvText/wrapper';
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { DRAG_HANDLE_CLASSNAME } from 'features/nodes/types/constants';
import type { NodeExecutionState } from 'features/nodes/types/invocation';
import { zNodeStatus } from 'features/nodes/types/invocation';
@ -29,8 +29,8 @@ const InvocationNodeStatusIndicator = ({ nodeId }: Props) => {
const selectNodeExecutionState = useMemo(
() =>
createMemoizedSelector(
stateSelector,
({ nodes }) => nodes.nodeExecutionStates[nodeId]
selectNodesSlice,
(nodes) => nodes.nodeExecutionStates[nodeId]
),
[nodeId]
);

View File

@ -1,7 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import InvocationNode from 'features/nodes/components/flow/nodes/Invocation/InvocationNode';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import type { InvocationNodeData } from 'features/nodes/types/invocation';
import { memo, useMemo } from 'react';
import type { NodeProps } from 'reactflow';
@ -14,7 +14,7 @@ const InvocationNodeWrapper = (props: NodeProps<InvocationNodeData>) => {
const hasTemplateSelector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodeTemplates }) =>
createMemoizedSelector(selectNodeTemplatesSlice, (nodeTemplates) =>
Boolean(nodeTemplates.templates[type])
),
[type]

View File

@ -1,5 +1,4 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import type { InvContextMenuProps } from 'common/components/InvContextMenu/InvContextMenu';
import { InvContextMenu } from 'common/components/InvContextMenu/InvContextMenu';
@ -10,6 +9,7 @@ import { useFieldInputKind } from 'features/nodes/hooks/useFieldInputKind';
import { useFieldLabel } from 'features/nodes/hooks/useFieldLabel';
import { useFieldTemplateTitle } from 'features/nodes/hooks/useFieldTemplateTitle';
import {
selectWorkflowSlice,
workflowExposedFieldAdded,
workflowExposedFieldRemoved,
} from 'features/nodes/store/workflowSlice';
@ -38,7 +38,7 @@ const FieldContextMenu = ({ nodeId, fieldName, kind, children }: Props) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ workflow }) => {
createMemoizedSelector(selectWorkflowSlice, (workflow) => {
const isExposed = Boolean(
workflow.exposedFields.find(
(f) => f.nodeId === nodeId && f.fieldName === fieldName

View File

@ -26,7 +26,7 @@ const ImageFieldInputComponent = (
) => {
const { nodeId, field } = props;
const dispatch = useAppDispatch();
const isConnected = useAppSelector((state) => state.system.isConnected);
const isConnected = useAppSelector((s) => s.system.isConnected);
const { currentData: imageDTO, isError } = useGetImageDTOQuery(
field.value?.image_name ?? skipToken
);

View File

@ -1,12 +1,11 @@
import type { ChakraProps } from '@chakra-ui/react';
import { Box, useToken } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import NodeSelectionOverlay from 'common/components/NodeSelectionOverlay';
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
import { useMouseOverNode } from 'features/nodes/hooks/useMouseOverNode';
import { nodeExclusivelySelected } from 'features/nodes/store/nodesSlice';
import { nodeExclusivelySelected , selectNodesSlice } from 'features/nodes/store/nodesSlice';
import {
DRAG_HANDLE_CLASSNAME,
NODE_WIDTH,
@ -29,8 +28,8 @@ const NodeWrapper = (props: NodeWrapperProps) => {
const selectIsInProgress = useMemo(
() =>
createMemoizedSelector(
stateSelector,
({ nodes }) =>
selectNodesSlice,
(nodes) =>
nodes.nodeExecutionStates[nodeId]?.status ===
zNodeStatus.enum.IN_PROGRESS
),
@ -47,7 +46,7 @@ const NodeWrapper = (props: NodeWrapperProps) => {
const dispatch = useAppDispatch();
const opacity = useAppSelector((state) => state.nodes.nodeOpacity);
const opacity = useAppSelector((s) => s.nodes.nodeOpacity);
const { onCloseGlobal } = useGlobalMenuCloseTrigger();
const handleClick = useCallback(

View File

@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
const NodeOpacitySlider = () => {
const dispatch = useAppDispatch();
const nodeOpacity = useAppSelector((state) => state.nodes.nodeOpacity);
const nodeOpacity = useAppSelector((s) => s.nodes.nodeOpacity);
const { t } = useTranslation();
const handleChange = useCallback(

View File

@ -20,10 +20,10 @@ const ViewportControls = () => {
const { zoomIn, zoomOut, fitView } = useReactFlow();
const dispatch = useAppDispatch();
// const shouldShowFieldTypeLegend = useAppSelector(
// (state) => state.nodes.shouldShowFieldTypeLegend
// (s) => s.nodes.shouldShowFieldTypeLegend
// );
const shouldShowMinimapPanel = useAppSelector(
(state) => state.nodes.shouldShowMinimapPanel
(s) => s.nodes.shouldShowMinimapPanel
);
const handleClickedZoomIn = useCallback(() => {

View File

@ -6,8 +6,8 @@ import { useTranslation } from 'react-i18next';
const TopCenterPanel = () => {
const { t } = useTranslation();
const name = useAppSelector((state) => state.workflow.name);
const isTouched = useAppSelector((state) => state.workflow.isTouched);
const name = useAppSelector((s) => s.workflow.name);
const isTouched = useAppSelector((s) => s.workflow.isTouched);
const isWorkflowLibraryEnabled =
useFeatureStatus('workflowLibrary').isFeatureEnabled;

View File

@ -1,6 +1,5 @@
import { Divider, Flex, Heading, useDisclosure } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InvControl } from 'common/components/InvControl/InvControl';
import {
@ -15,17 +14,16 @@ import { InvSwitch } from 'common/components/InvSwitch/wrapper';
import ReloadNodeTemplatesButton from 'features/nodes/components/flow/panels/TopRightPanel/ReloadSchemaButton';
import {
selectionModeChanged,
shouldAnimateEdgesChanged,
selectNodesSlice, shouldAnimateEdgesChanged,
shouldColorEdgesChanged,
shouldSnapToGridChanged,
shouldValidateGraphChanged,
} from 'features/nodes/store/nodesSlice';
shouldValidateGraphChanged } from 'features/nodes/store/nodesSlice';
import type { ChangeEvent, ReactNode } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { SelectionMode } from 'reactflow';
const selector = createMemoizedSelector(stateSelector, ({ nodes }) => {
const selector = createMemoizedSelector(selectNodesSlice, (nodes) => {
const {
shouldAnimateEdges,
shouldValidateGraph,

View File

@ -1,11 +1,11 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { memo } from 'react';
const selector = createMemoizedSelector(stateSelector, ({ nodes }) => {
const selector = createMemoizedSelector(selectNodesSlice, (nodes) => {
const lastSelectedNodeId =
nodes.selectedNodes[nodes.selectedNodes.length - 1];

View File

@ -1,6 +1,5 @@
import { Box, Flex, HStack } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { InvControl } from 'common/components/InvControl/InvControl';
@ -8,6 +7,8 @@ import { InvText } from 'common/components/InvText/wrapper';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import NotesTextarea from 'features/nodes/components/flow/nodes/Invocation/NotesTextarea';
import { useNodeNeedsUpdate } from 'features/nodes/hooks/useNodeNeedsUpdate';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
@ -15,8 +16,9 @@ import { useTranslation } from 'react-i18next';
import EditableNodeTitle from './details/EditableNodeTitle';
const selector = createMemoizedSelector(
stateSelector,
({ nodes, nodeTemplates }) => {
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const lastSelectedNodeId =
nodes.selectedNodes[nodes.selectedNodes.length - 1];

View File

@ -1,10 +1,11 @@
import { Box, Flex } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
@ -14,8 +15,9 @@ import type { AnyResult } from 'services/events/types';
import ImageOutputPreview from './outputs/ImageOutputPreview';
const selector = createMemoizedSelector(
stateSelector,
({ nodes, nodeTemplates }) => {
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const lastSelectedNodeId =
nodes.selectedNodes[nodes.selectedNodes.length - 1];

View File

@ -1,14 +1,16 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createMemoizedSelector(
stateSelector,
({ nodes, nodeTemplates }) => {
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const lastSelectedNodeId =
nodes.selectedNodes[nodes.selectedNodes.length - 1];

View File

@ -1,6 +1,5 @@
import { Flex } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InvControl } from 'common/components/InvControl/InvControl';
import { InvControlGroup } from 'common/components/InvControl/InvControlGroup';
@ -8,19 +7,18 @@ import { InvInput } from 'common/components/InvInput/InvInput';
import { InvTextarea } from 'common/components/InvTextarea/InvTextarea';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import {
workflowAuthorChanged,
selectWorkflowSlice, workflowAuthorChanged,
workflowContactChanged,
workflowDescriptionChanged,
workflowNameChanged,
workflowNotesChanged,
workflowTagsChanged,
workflowVersionChanged,
} from 'features/nodes/store/workflowSlice';
workflowVersionChanged } from 'features/nodes/store/workflowSlice';
import type { ChangeEvent } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createMemoizedSelector(stateSelector, ({ workflow }) => {
const selector = createMemoizedSelector(selectWorkflowSlice, (workflow) => {
const { author, name, description, tags, version, contact, notes } = workflow;
return {

View File

@ -1,21 +1,20 @@
import { Box, Flex } from '@chakra-ui/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import LinearViewField from 'features/nodes/components/flow/nodes/Invocation/fields/LinearViewField';
import { selectWorkflowSlice } from 'features/nodes/store/workflowSlice';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createMemoizedSelector(stateSelector, ({ workflow }) => {
return {
fields: workflow.exposedFields,
};
});
const selector = createMemoizedSelector(
selectWorkflowSlice,
(workflow) => workflow.exposedFields
);
const WorkflowLinearTab = () => {
const { fields } = useAppSelector(selector);
const fields = useAppSelector(selector);
const { t } = useTranslation();
return (

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';
import { TEMPLATE_BUILDER_MAP } from 'features/nodes/util/schema/buildFieldInputTemplate';
@ -10,23 +11,27 @@ import { useMemo } from 'react';
export const useAnyOrDirectInputFieldNames = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
const fields = map(nodeTemplate.inputs).filter(
(field) =>
(['any', 'direct'].includes(field.input) ||
field.type.isCollectionOrScalar) &&
keys(TEMPLATE_BUILDER_MAP).includes(field.type.name)
);
return getSortedFilteredFieldNames(fields);
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
const fields = map(nodeTemplate.inputs).filter(
(field) =>
(['any', 'direct'].includes(field.input) ||
field.type.isCollectionOrScalar) &&
keys(TEMPLATE_BUILDER_MAP).includes(field.type.name)
);
return getSortedFilteredFieldNames(fields);
}),
),
[nodeId]
);

View File

@ -20,7 +20,7 @@ export const SHARED_NODE_PROPERTIES: Partial<Node> = {
export const useBuildNode = () => {
const nodeTemplates = useAppSelector(
(state) => state.nodeTemplates.templates
(s) => s.nodeTemplates.templates
);
const flow = useReactFlow();

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';
import { TEMPLATE_BUILDER_MAP } from 'features/nodes/util/schema/buildFieldInputTemplate';
@ -10,26 +11,30 @@ import { useMemo } from 'react';
export const useConnectionInputFieldNames = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
// get the visible fields
const fields = map(nodeTemplate.inputs).filter(
(field) =>
(field.input === 'connection' &&
!field.type.isCollectionOrScalar) ||
!keys(TEMPLATE_BUILDER_MAP).includes(field.type.name)
);
// get the visible fields
const fields = map(nodeTemplate.inputs).filter(
(field) =>
(field.input === 'connection' &&
!field.type.isCollectionOrScalar) ||
!keys(TEMPLATE_BUILDER_MAP).includes(field.type.name)
);
return getSortedFilteredFieldNames(fields);
}),
return getSortedFilteredFieldNames(fields);
}
),
[nodeId]
);

View File

@ -1,14 +1,14 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { makeConnectionErrorSelector } from 'features/nodes/store/util/makeIsConnectionValidSelector';
import { useMemo } from 'react';
import { useFieldType } from './useFieldType.ts';
const selectIsConnectionInProgress = createMemoizedSelector(
stateSelector,
({ nodes }) =>
selectNodesSlice,
(nodes) =>
nodes.connectionStartFieldType !== null &&
nodes.connectionStartParams !== null
);
@ -28,7 +28,7 @@ export const useConnectionState = ({
const selectIsConnected = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) =>
createMemoizedSelector(selectNodesSlice, (nodes) =>
Boolean(
nodes.edges.filter((edge) => {
return (
@ -55,7 +55,7 @@ export const useConnectionState = ({
const selectIsConnectionStartField = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) =>
createMemoizedSelector(selectNodesSlice, (nodes) =>
Boolean(
nodes.connectionStartParams?.nodeId === nodeId &&
nodes.connectionStartParams?.handleId === fieldName &&

View File

@ -1,24 +1,29 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { compareVersions } from 'compare-versions';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useDoNodeVersionsMatch = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
if (!nodeTemplate?.version || !node.data?.version) {
return false;
}
return compareVersions(nodeTemplate.version, node.data.version) === 0;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
if (!nodeTemplate?.version || !node.data?.version) {
return false;
}
return compareVersions(nodeTemplate.version, node.data.version) === 0;
}),
),
[nodeId]
);

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useDoesInputHaveValue = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldInstance = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldInputInstance = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,21 +1,26 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldInputKind = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
const fieldTemplate = nodeTemplate?.inputs[fieldName];
return fieldTemplate?.input;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
const fieldTemplate = nodeTemplate?.inputs[fieldName];
return fieldTemplate?.input;
}),
),
[fieldName, nodeId]
);

View File

@ -1,20 +1,25 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldInputTemplate = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.inputs[fieldName];
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.inputs[fieldName];
}),
),
[fieldName, nodeId]
);

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldLabel = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldOutputInstance = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,20 +1,25 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useFieldOutputTemplate = (nodeId: string, fieldName: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.outputs[fieldName];
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.outputs[fieldName];
}),
),
[fieldName, nodeId]
);

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { KIND_MAP } from 'features/nodes/types/constants';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
@ -12,14 +13,18 @@ export const useFieldTemplate = (
) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.[KIND_MAP[kind]][fieldName];
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.[KIND_MAP[kind]][fieldName];
}),
),
[fieldName, kind, nodeId]
);

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { KIND_MAP } from 'features/nodes/types/constants';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
@ -12,14 +13,18 @@ export const useFieldTemplateTitle = (
) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.[KIND_MAP[kind]][fieldName]?.title;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.[KIND_MAP[kind]][fieldName]?.title;
}),
),
[fieldName, kind, nodeId]
);

View File

@ -1,6 +1,6 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { KIND_MAP } from 'features/nodes/types/constants';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
@ -12,7 +12,7 @@ export const useFieldType = (
) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return;

View File

@ -1,17 +1,21 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getNeedsUpdate } from 'features/nodes/util/node/nodeUpdate';
const selector = createMemoizedSelector(stateSelector, (state) =>
state.nodes.nodes.filter(isInvocationNode).some((node) => {
const template = state.nodeTemplates.templates[node.data.type];
if (!template) {
return false;
}
return getNeedsUpdate(node, template);
})
const selector = createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) =>
nodes.nodes.filter(isInvocationNode).some((node) => {
const template = nodeTemplates.templates[node.data.type];
if (!template) {
return false;
}
return getNeedsUpdate(node, template);
})
);
export const useGetNodesNeedUpdate = () => {

View File

@ -1,6 +1,6 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { some } from 'lodash-es';
import { useMemo } from 'react';
@ -8,7 +8,7 @@ import { useMemo } from 'react';
export const useHasImageOutput = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useIsIntermediate = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;

View File

@ -15,7 +15,7 @@ import { useReactFlow } from 'reactflow';
export const useIsValidConnection = () => {
const flow = useReactFlow();
const shouldValidateGraph = useAppSelector(
(state) => state.nodes.shouldValidateGraph
(s) => s.nodes.shouldValidateGraph
);
const isValidConnection = useCallback(
({ source, sourceHandle, target, targetHandle }: Connection): boolean => {

View File

@ -1,20 +1,25 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useNodeClassification = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.classification;
}
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate?.classification;
}),
),
[nodeId]
);

View File

@ -1,12 +1,12 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { useMemo } from 'react';
export const useNodeData = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
return node?.data;
}),

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useNodeLabel = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getNeedsUpdate } from 'features/nodes/util/node/nodeUpdate';
import { useMemo } from 'react';
@ -8,14 +9,18 @@ import { useMemo } from 'react';
export const useNodeNeedsUpdate = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
const template = nodeTemplates.templates[node?.data.type ?? ''];
if (isInvocationNode(node) && template) {
return getNeedsUpdate(node, template);
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
const template = nodeTemplates.templates[node?.data.type ?? ''];
if (isInvocationNode(node) && template) {
return getNeedsUpdate(node, template);
}
return false;
}
return false;
}),
),
[nodeId]
);

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useNodePack = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;

View File

@ -1,16 +1,21 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { useMemo } from 'react';
export const useNodeTemplate = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate;
}),
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
const nodeTemplate = nodeTemplates.templates[node?.data.type ?? ''];
return nodeTemplate;
}
),
[nodeId]
);

View File

@ -1,6 +1,6 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import type { InvocationTemplate } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
@ -8,8 +8,8 @@ export const useNodeTemplateByType = (type: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(
stateSelector,
({ nodeTemplates }): InvocationTemplate | undefined => {
selectNodeTemplatesSlice,
(nodeTemplates): InvocationTemplate | undefined => {
return nodeTemplates.templates[type];
}
),

View File

@ -1,23 +1,28 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useNodeTemplateTitle = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
}
const nodeTemplate = node
? nodeTemplates.templates[node.data.type]
: undefined;
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;
}
const nodeTemplate = node
? nodeTemplates.templates[node.data.type]
: undefined;
return nodeTemplate?.title;
}),
return nodeTemplate?.title;
}
),
[nodeId]
);

View File

@ -1,6 +1,7 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';
import { map } from 'lodash-es';
@ -9,18 +10,22 @@ import { useMemo } from 'react';
export const useOutputFieldNames = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes, nodeTemplates }) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
createMemoizedSelector(
selectNodesSlice,
selectNodeTemplatesSlice,
(nodes, nodeTemplates) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return [];
}
const nodeTemplate = nodeTemplates.templates[node.data.type];
if (!nodeTemplate) {
return [];
}
return getSortedFilteredFieldNames(map(nodeTemplate.outputs));
}),
return getSortedFilteredFieldNames(map(nodeTemplate.outputs));
}
),
[nodeId]
);

View File

@ -1,13 +1,13 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { isInvocationNode } from 'features/nodes/types/invocation';
import { useMemo } from 'react';
export const useUseCache = (nodeId: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(stateSelector, ({ nodes }) => {
createMemoizedSelector(selectNodesSlice, (nodes) => {
const node = nodes.nodes.find((node) => node.id === nodeId);
if (!isInvocationNode(node)) {
return false;

View File

@ -1,5 +1,6 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import type { RootState } from 'app/store/store';
import type { InvocationTemplate } from 'features/nodes/types/invocation';
import type { NodeTemplatesState } from './types';
@ -24,3 +25,6 @@ const nodesTemplatesSlice = createSlice({
export const { nodeTemplatesBuilt } = nodesTemplatesSlice.actions;
export default nodesTemplatesSlice.reducer;
export const selectNodeTemplatesSlice = (state: RootState) =>
state.nodeTemplates;

View File

@ -1,5 +1,6 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice, isAnyOf } from '@reduxjs/toolkit';
import type { RootState } from 'app/store/store';
import { workflowLoaded } from 'features/nodes/store/actions';
import { nodeTemplatesBuilt } from 'features/nodes/store/nodeTemplatesSlice';
import { SHARED_NODE_PROPERTIES } from 'features/nodes/types/constants';
@ -987,3 +988,5 @@ export const isAnyNodeOrEdgeMutation = isAnyOf(
);
export default nodesSlice.reducer;
export const selectNodesSlice = (state: RootState) => state.nodes;

View File

@ -1,5 +1,5 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import type { FieldType } from 'features/nodes/types/field';
import i18n from 'i18next';
import type { HandleType } from 'reactflow';
@ -18,13 +18,13 @@ export const makeConnectionErrorSelector = (
handleType: HandleType,
fieldType?: FieldType
) => {
return createMemoizedSelector(stateSelector, (state): string | undefined => {
return createMemoizedSelector(selectNodesSlice, (nodesSlice) => {
if (!fieldType) {
return i18n.t('nodes.noFieldType');
}
const { connectionStartFieldType, connectionStartParams, nodes, edges } =
state.nodes;
nodesSlice;
if (!connectionStartParams || !connectionStartFieldType) {
return i18n.t('nodes.noConnectionInProgress');

View File

@ -1,5 +1,6 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import type { RootState } from 'app/store/store';
import { workflowLoaded } from 'features/nodes/store/actions';
import {
isAnyNodeOrEdgeMutation,
@ -120,3 +121,5 @@ export const {
} = workflowSlice.actions;
export default workflowSlice.reducer;
export const selectWorkflowSlice = (state: RootState) => state.workflow;