mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): split workflow editor settings to separate slice
We need the undoable slice to be only undoable state - settings are not undoable.
This commit is contained in:
parent
27826369f0
commit
9c0d44b412
@ -22,6 +22,7 @@ import { hrfPersistConfig, hrfSlice } from 'features/hrf/store/hrfSlice';
|
||||
import { loraPersistConfig, loraSlice } from 'features/lora/store/loraSlice';
|
||||
import { modelManagerV2PersistConfig, modelManagerV2Slice } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||
import { nodesPersistConfig, nodesSlice, nodesUndoableConfig } from 'features/nodes/store/nodesSlice';
|
||||
import { workflowSettingsPersistConfig, workflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import { workflowPersistConfig, workflowSlice } from 'features/nodes/store/workflowSlice';
|
||||
import { generationPersistConfig, generationSlice } from 'features/parameters/store/generationSlice';
|
||||
import { postprocessingPersistConfig, postprocessingSlice } from 'features/parameters/store/postprocessingSlice';
|
||||
@ -66,6 +67,7 @@ const allReducers = {
|
||||
[workflowSlice.name]: workflowSlice.reducer,
|
||||
[hrfSlice.name]: hrfSlice.reducer,
|
||||
[controlLayersSlice.name]: undoable(controlLayersSlice.reducer, controlLayersUndoableConfig),
|
||||
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
||||
[api.reducerPath]: api.reducer,
|
||||
};
|
||||
|
||||
@ -111,6 +113,7 @@ const persistConfigs: { [key in keyof typeof allReducers]?: PersistConfig } = {
|
||||
[modelManagerV2PersistConfig.name]: modelManagerV2PersistConfig,
|
||||
[hrfPersistConfig.name]: hrfPersistConfig,
|
||||
[controlLayersPersistConfig.name]: controlLayersPersistConfig,
|
||||
[workflowSettingsPersistConfig.name]: workflowSettingsPersistConfig,
|
||||
};
|
||||
|
||||
const unserialize: UnserializeFunction = (data, key) => {
|
||||
|
@ -10,6 +10,7 @@ import type { Layer } from 'features/controlLayers/store/types';
|
||||
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt';
|
||||
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||
import { selectWorkflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
||||
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||
@ -31,11 +32,12 @@ const selector = createMemoizedSelector(
|
||||
selectGenerationSlice,
|
||||
selectSystemSlice,
|
||||
selectNodesSlice,
|
||||
selectWorkflowSettingsSlice,
|
||||
selectDynamicPromptsSlice,
|
||||
selectControlLayersSlice,
|
||||
activeTabNameSelector,
|
||||
],
|
||||
(controlAdapters, generation, system, nodes, dynamicPrompts, controlLayers, activeTabName) => {
|
||||
(controlAdapters, generation, system, nodes, workflowSettings, dynamicPrompts, controlLayers, activeTabName) => {
|
||||
const { model } = generation;
|
||||
const { size } = controlLayers.present;
|
||||
const { positivePrompt } = controlLayers.present;
|
||||
@ -50,7 +52,7 @@ const selector = createMemoizedSelector(
|
||||
}
|
||||
|
||||
if (activeTabName === 'workflows') {
|
||||
if (nodes.shouldValidateGraph) {
|
||||
if (workflowSettings.shouldValidateGraph) {
|
||||
if (!nodes.nodes.length) {
|
||||
reasons.push({ content: i18n.t('parameters.invoke.noNodesInGraph') });
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ export const Flow = memo(() => {
|
||||
const nodes = useAppSelector((s) => s.nodes.present.nodes);
|
||||
const edges = useAppSelector((s) => s.nodes.present.edges);
|
||||
const viewport = useAppSelector((s) => s.nodes.present.viewport);
|
||||
const shouldSnapToGrid = useAppSelector((s) => s.nodes.present.shouldSnapToGrid);
|
||||
const selectionMode = useAppSelector((s) => s.nodes.present.selectionMode);
|
||||
const shouldSnapToGrid = useAppSelector((s) => s.workflowSettings.shouldSnapToGrid);
|
||||
const selectionMode = useAppSelector((s) => s.workflowSettings.selectionMode);
|
||||
const flowWrapper = useRef<HTMLDivElement>(null);
|
||||
const cursorPosition = useRef<XYPosition | null>(null);
|
||||
const isValidConnection = useIsValidConnection();
|
||||
|
@ -3,17 +3,20 @@ 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 { selectWorkflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { memo } from 'react';
|
||||
import type { ConnectionLineComponentProps } from 'reactflow';
|
||||
import { getBezierPath } from 'reactflow';
|
||||
|
||||
const selectStroke = createSelector(selectNodesSlice, (nodes) =>
|
||||
nodes.shouldColorEdges ? getFieldColor(nodes.connectionStartFieldType) : colorTokenToCssVar('base.500')
|
||||
const selectStroke = createSelector([selectNodesSlice, selectWorkflowSettingsSlice], (nodes, workflowSettings) =>
|
||||
workflowSettings.shouldColorEdges ? getFieldColor(nodes.connectionStartFieldType) : colorTokenToCssVar('base.500')
|
||||
);
|
||||
|
||||
const selectClassName = createSelector(selectNodesSlice, (nodes) =>
|
||||
nodes.shouldAnimateEdges ? 'react-flow__custom_connection-path animated' : 'react-flow__custom_connection-path'
|
||||
const selectClassName = createSelector(selectWorkflowSettingsSlice, (workflowSettings) =>
|
||||
workflowSettings.shouldAnimateEdges
|
||||
? 'react-flow__custom_connection-path animated'
|
||||
: 'react-flow__custom_connection-path'
|
||||
);
|
||||
|
||||
const pathStyles: CSSProperties = { opacity: 0.8 };
|
||||
|
@ -27,7 +27,7 @@ const InvocationDefaultEdge = ({
|
||||
);
|
||||
|
||||
const { isSelected, shouldAnimate, stroke, label } = useAppSelector(selector);
|
||||
const shouldShowEdgeLabels = useAppSelector((s) => s.nodes.present.shouldShowEdgeLabels);
|
||||
const shouldShowEdgeLabels = useAppSelector((s) => s.workflowSettings.shouldShowEdgeLabels);
|
||||
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX,
|
||||
|
@ -2,6 +2,7 @@ import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { colorTokenToCssVar } from 'common/util/colorTokenToCssVar';
|
||||
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||
import { selectFieldOutputTemplate, selectNodeTemplate } from 'features/nodes/store/selectors';
|
||||
import { selectWorkflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||
|
||||
import { getFieldColor } from './getEdgeColor';
|
||||
@ -22,7 +23,8 @@ export const makeEdgeSelector = (
|
||||
) =>
|
||||
createMemoizedSelector(
|
||||
selectNodesSlice,
|
||||
(nodes): { isSelected: boolean; shouldAnimate: boolean; stroke: string; label: string } => {
|
||||
selectWorkflowSettingsSlice,
|
||||
(nodes, workflowSettings): { isSelected: boolean; shouldAnimate: boolean; stroke: string; label: string } => {
|
||||
const sourceNode = nodes.nodes.find((node) => node.id === source);
|
||||
const targetNode = nodes.nodes.find((node) => node.id === target);
|
||||
|
||||
@ -36,7 +38,7 @@ export const makeEdgeSelector = (
|
||||
const outputFieldTemplate = selectFieldOutputTemplate(nodes, sourceNode.id, sourceHandleId);
|
||||
const sourceType = isInvocationToInvocationEdge ? outputFieldTemplate?.type : undefined;
|
||||
|
||||
const stroke = sourceType && nodes.shouldColorEdges ? getFieldColor(sourceType) : colorTokenToCssVar('base.500');
|
||||
const stroke = sourceType && workflowSettings.shouldColorEdges ? getFieldColor(sourceType) : colorTokenToCssVar('base.500');
|
||||
|
||||
const sourceNodeTemplate = selectNodeTemplate(nodes, sourceNode.id);
|
||||
const targetNodeTemplate = selectNodeTemplate(nodes, targetNode.id);
|
||||
@ -45,7 +47,7 @@ export const makeEdgeSelector = (
|
||||
|
||||
return {
|
||||
isSelected,
|
||||
shouldAnimate: nodes.shouldAnimateEdges && isSelected,
|
||||
shouldAnimate: workflowSettings.shouldAnimateEdges && isSelected,
|
||||
stroke,
|
||||
label,
|
||||
};
|
||||
|
@ -39,7 +39,7 @@ const NodeWrapper = (props: NodeWrapperProps) => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const opacity = useAppSelector((s) => s.nodes.present.nodeOpacity);
|
||||
const opacity = useAppSelector((s) => s.workflowSettings.nodeOpacity);
|
||||
const { onCloseGlobal } = useGlobalMenuClose();
|
||||
|
||||
const handleClick = useCallback(
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeSlider, Flex } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { nodeOpacityChanged } from 'features/nodes/store/nodesSlice';
|
||||
import { nodeOpacityChanged } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const NodeOpacitySlider = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const nodeOpacity = useAppSelector((s) => s.nodes.present.nodeOpacity);
|
||||
const nodeOpacity = useAppSelector((s) => s.workflowSettings.nodeOpacity);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChange = useCallback(
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { ButtonGroup, IconButton } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import {
|
||||
// shouldShowFieldTypeLegendChanged,
|
||||
shouldShowMinimapPanelChanged,
|
||||
} from 'features/nodes/store/nodesSlice';
|
||||
import { shouldShowMinimapPanelChanged } from 'features/nodes/store/workflowSettingsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@ -21,7 +18,7 @@ const ViewportControls = () => {
|
||||
// const shouldShowFieldTypeLegend = useAppSelector(
|
||||
// (s) => s.nodes.present.shouldShowFieldTypeLegend
|
||||
// );
|
||||
const shouldShowMinimapPanel = useAppSelector((s) => s.nodes.present.shouldShowMinimapPanel);
|
||||
const shouldShowMinimapPanel = useAppSelector((s) => s.workflowSettings.shouldShowMinimapPanel);
|
||||
|
||||
const handleClickedZoomIn = useCallback(() => {
|
||||
zoomIn();
|
||||
|
@ -16,7 +16,7 @@ const minimapStyles: SystemStyleObject = {
|
||||
};
|
||||
|
||||
const MinimapPanel = () => {
|
||||
const shouldShowMinimapPanel = useAppSelector((s) => s.nodes.present.shouldShowMinimapPanel);
|
||||
const shouldShowMinimapPanel = useAppSelector((s) => s.workflowSettings.shouldShowMinimapPanel);
|
||||
|
||||
return (
|
||||
<Flex gap={2} position="absolute" bottom={0} insetInlineEnd={0}>
|
||||
|
@ -21,13 +21,13 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import ReloadNodeTemplatesButton from 'features/nodes/components/flow/panels/TopRightPanel/ReloadSchemaButton';
|
||||
import {
|
||||
selectionModeChanged,
|
||||
selectNodesSlice,
|
||||
selectWorkflowSettingsSlice,
|
||||
shouldAnimateEdgesChanged,
|
||||
shouldColorEdgesChanged,
|
||||
shouldShowEdgeLabelsChanged,
|
||||
shouldSnapToGridChanged,
|
||||
shouldValidateGraphChanged,
|
||||
} from 'features/nodes/store/nodesSlice';
|
||||
} from 'features/nodes/store/workflowSettingsSlice';
|
||||
import type { ChangeEvent, ReactNode } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -35,7 +35,7 @@ import { SelectionMode } from 'reactflow';
|
||||
|
||||
const formLabelProps: FormLabelProps = { flexGrow: 1 };
|
||||
|
||||
const selector = createMemoizedSelector(selectNodesSlice, (nodes) => {
|
||||
const selector = createMemoizedSelector(selectWorkflowSettingsSlice, (workflowSettings) => {
|
||||
const {
|
||||
shouldAnimateEdges,
|
||||
shouldValidateGraph,
|
||||
@ -43,7 +43,7 @@ const selector = createMemoizedSelector(selectNodesSlice, (nodes) => {
|
||||
shouldColorEdges,
|
||||
shouldShowEdgeLabels,
|
||||
selectionMode,
|
||||
} = nodes;
|
||||
} = workflowSettings;
|
||||
return {
|
||||
shouldAnimateEdges,
|
||||
shouldValidateGraph,
|
||||
|
@ -13,7 +13,7 @@ import type { Connection, Node } from 'reactflow';
|
||||
|
||||
export const useIsValidConnection = () => {
|
||||
const store = useAppStore();
|
||||
const shouldValidateGraph = useAppSelector((s) => s.nodes.present.shouldValidateGraph);
|
||||
const shouldValidateGraph = useAppSelector((s) => s.workflowSettings.shouldValidateGraph);
|
||||
const isValidConnection = useCallback(
|
||||
({ source, sourceHandle, target, targetHandle }: Connection): boolean => {
|
||||
// Connection must have valid targets
|
||||
|
@ -57,15 +57,7 @@ import type {
|
||||
Viewport,
|
||||
XYPosition,
|
||||
} from 'reactflow';
|
||||
import {
|
||||
addEdge,
|
||||
applyEdgeChanges,
|
||||
applyNodeChanges,
|
||||
getConnectedEdges,
|
||||
getIncomers,
|
||||
getOutgoers,
|
||||
SelectionMode,
|
||||
} from 'reactflow';
|
||||
import { addEdge, applyEdgeChanges, applyNodeChanges, getConnectedEdges, getIncomers, getOutgoers } from 'reactflow';
|
||||
import type { UndoableOptions } from 'redux-undo';
|
||||
import {
|
||||
socketGeneratorProgress,
|
||||
@ -99,21 +91,13 @@ const initialNodesState: NodesState = {
|
||||
connectionMade: false,
|
||||
modifyingEdge: false,
|
||||
addNewNodePosition: null,
|
||||
shouldShowMinimapPanel: true,
|
||||
shouldValidateGraph: true,
|
||||
shouldAnimateEdges: true,
|
||||
shouldSnapToGrid: false,
|
||||
shouldColorEdges: true,
|
||||
shouldShowEdgeLabels: false,
|
||||
isAddNodePopoverOpen: false,
|
||||
nodeOpacity: 1,
|
||||
selectedNodes: [],
|
||||
selectedEdges: [],
|
||||
nodeExecutionStates: {},
|
||||
viewport: { x: 0, y: 0, zoom: 1 },
|
||||
nodesToCopy: [],
|
||||
edgesToCopy: [],
|
||||
selectionMode: SelectionMode.Partial,
|
||||
};
|
||||
|
||||
type FieldValueAction<T extends FieldValue> = PayloadAction<{
|
||||
@ -538,31 +522,10 @@ export const nodesSlice = createSlice({
|
||||
}
|
||||
node.data.notes = value;
|
||||
},
|
||||
shouldShowMinimapPanelChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowMinimapPanel = action.payload;
|
||||
},
|
||||
nodeEditorReset: (state) => {
|
||||
state.nodes = [];
|
||||
state.edges = [];
|
||||
},
|
||||
shouldValidateGraphChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldValidateGraph = action.payload;
|
||||
},
|
||||
shouldAnimateEdgesChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldAnimateEdges = action.payload;
|
||||
},
|
||||
shouldShowEdgeLabelsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowEdgeLabels = action.payload;
|
||||
},
|
||||
shouldSnapToGridChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldSnapToGrid = action.payload;
|
||||
},
|
||||
shouldColorEdgesChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldColorEdges = action.payload;
|
||||
},
|
||||
nodeOpacityChanged: (state, action: PayloadAction<number>) => {
|
||||
state.nodeOpacity = action.payload;
|
||||
},
|
||||
viewportChanged: (state, action: PayloadAction<Viewport>) => {
|
||||
state.viewport = action.payload;
|
||||
},
|
||||
@ -700,9 +663,6 @@ export const nodesSlice = createSlice({
|
||||
state.connectionStartParams = null;
|
||||
state.connectionStartFieldType = null;
|
||||
},
|
||||
selectionModeChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.selectionMode = action.payload ? SelectionMode.Full : SelectionMode.Partial;
|
||||
},
|
||||
nodeTemplatesBuilt: (state, action: PayloadAction<Record<string, InvocationTemplate>>) => {
|
||||
state.templates = action.payload;
|
||||
},
|
||||
@ -819,7 +779,6 @@ export const {
|
||||
nodeIsOpenChanged,
|
||||
nodeLabelChanged,
|
||||
nodeNotesChanged,
|
||||
nodeOpacityChanged,
|
||||
nodesChanged,
|
||||
nodesDeleted,
|
||||
nodeUseCacheChanged,
|
||||
@ -828,17 +787,10 @@ export const {
|
||||
selectedEdgesChanged,
|
||||
selectedNodesChanged,
|
||||
selectionCopied,
|
||||
selectionModeChanged,
|
||||
selectionPasted,
|
||||
shouldAnimateEdgesChanged,
|
||||
shouldColorEdgesChanged,
|
||||
shouldShowMinimapPanelChanged,
|
||||
shouldSnapToGridChanged,
|
||||
shouldValidateGraphChanged,
|
||||
viewportChanged,
|
||||
edgeAdded,
|
||||
nodeTemplatesBuilt,
|
||||
shouldShowEdgeLabelsChanged,
|
||||
undo,
|
||||
redo,
|
||||
} = nodesSlice.actions;
|
||||
|
@ -6,7 +6,7 @@ import type {
|
||||
NodeExecutionState,
|
||||
} from 'features/nodes/types/invocation';
|
||||
import type { WorkflowV3 } from 'features/nodes/types/workflow';
|
||||
import type { OnConnectStartParams, SelectionMode, Viewport, XYPosition } from 'reactflow';
|
||||
import type { OnConnectStartParams, Viewport, XYPosition } from 'reactflow';
|
||||
|
||||
export type NodesState = {
|
||||
_version: 1;
|
||||
@ -17,13 +17,6 @@ export type NodesState = {
|
||||
connectionStartFieldType: FieldType | null;
|
||||
connectionMade: boolean;
|
||||
modifyingEdge: boolean;
|
||||
shouldShowMinimapPanel: boolean;
|
||||
shouldValidateGraph: boolean;
|
||||
shouldAnimateEdges: boolean;
|
||||
nodeOpacity: number;
|
||||
shouldSnapToGrid: boolean;
|
||||
shouldColorEdges: boolean;
|
||||
shouldShowEdgeLabels: boolean;
|
||||
selectedNodes: string[];
|
||||
selectedEdges: string[];
|
||||
nodeExecutionStates: Record<string, NodeExecutionState>;
|
||||
@ -32,7 +25,6 @@ export type NodesState = {
|
||||
edgesToCopy: InvocationNodeEdge[];
|
||||
isAddNodePopoverOpen: boolean;
|
||||
addNewNodePosition: XYPosition | null;
|
||||
selectionMode: SelectionMode;
|
||||
};
|
||||
|
||||
export type WorkflowMode = 'edit' | 'view';
|
||||
|
@ -0,0 +1,87 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { PersistConfig, RootState } from 'app/store/store';
|
||||
import { SelectionMode } from 'reactflow';
|
||||
|
||||
export type WorkflowSettingsState = {
|
||||
_version: 1;
|
||||
shouldShowMinimapPanel: boolean;
|
||||
shouldValidateGraph: boolean;
|
||||
shouldAnimateEdges: boolean;
|
||||
nodeOpacity: number;
|
||||
shouldSnapToGrid: boolean;
|
||||
shouldColorEdges: boolean;
|
||||
shouldShowEdgeLabels: boolean;
|
||||
selectionMode: SelectionMode;
|
||||
};
|
||||
|
||||
const initialState: WorkflowSettingsState = {
|
||||
_version: 1,
|
||||
shouldShowMinimapPanel: true,
|
||||
shouldValidateGraph: true,
|
||||
shouldAnimateEdges: true,
|
||||
shouldSnapToGrid: false,
|
||||
shouldColorEdges: true,
|
||||
shouldShowEdgeLabels: false,
|
||||
nodeOpacity: 1,
|
||||
selectionMode: SelectionMode.Partial,
|
||||
};
|
||||
|
||||
export const workflowSettingsSlice = createSlice({
|
||||
name: 'workflowSettings',
|
||||
initialState,
|
||||
reducers: {
|
||||
shouldShowMinimapPanelChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowMinimapPanel = action.payload;
|
||||
},
|
||||
shouldValidateGraphChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldValidateGraph = action.payload;
|
||||
},
|
||||
shouldAnimateEdgesChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldAnimateEdges = action.payload;
|
||||
},
|
||||
shouldShowEdgeLabelsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowEdgeLabels = action.payload;
|
||||
},
|
||||
shouldSnapToGridChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldSnapToGrid = action.payload;
|
||||
},
|
||||
shouldColorEdgesChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldColorEdges = action.payload;
|
||||
},
|
||||
nodeOpacityChanged: (state, action: PayloadAction<number>) => {
|
||||
state.nodeOpacity = action.payload;
|
||||
},
|
||||
selectionModeChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.selectionMode = action.payload ? SelectionMode.Full : SelectionMode.Partial;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
shouldAnimateEdgesChanged,
|
||||
shouldColorEdgesChanged,
|
||||
shouldShowMinimapPanelChanged,
|
||||
shouldShowEdgeLabelsChanged,
|
||||
shouldSnapToGridChanged,
|
||||
shouldValidateGraphChanged,
|
||||
nodeOpacityChanged,
|
||||
selectionModeChanged,
|
||||
} = workflowSettingsSlice.actions;
|
||||
|
||||
export const selectWorkflowSettingsSlice = (state: RootState) => state.workflowSettings;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
const migrateWorkflowSettingsState = (state: any): any => {
|
||||
if (!('_version' in state)) {
|
||||
state._version = 1;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
export const workflowSettingsPersistConfig: PersistConfig<WorkflowSettingsState> = {
|
||||
name: workflowSettingsSlice.name,
|
||||
initialState,
|
||||
migrate: migrateWorkflowSettingsState,
|
||||
persistDenylist: [],
|
||||
};
|
Loading…
Reference in New Issue
Block a user