feat: introduce style and behavior improvements
This commit is contained in:

committed by
Ali BARIN

parent
737eb31776
commit
f08dc25711
@@ -165,6 +165,7 @@ function ChooseAppAndEventSubstep(props) {
|
|||||||
value={getOption(appOptions, step.appKey) || null}
|
value={getOption(appOptions, step.appKey) || null}
|
||||||
onChange={onAppChange}
|
onChange={onAppChange}
|
||||||
data-test="choose-app-autocomplete"
|
data-test="choose-app-autocomplete"
|
||||||
|
componentsProps={{ popper: { className: 'nowheel' } }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{step.appKey && (
|
{step.appKey && (
|
||||||
@@ -227,6 +228,7 @@ function ChooseAppAndEventSubstep(props) {
|
|||||||
value={getOption(actionOrTriggerOptions, step.key) || null}
|
value={getOption(actionOrTriggerOptions, step.key) || null}
|
||||||
onChange={onEventChange}
|
onChange={onEventChange}
|
||||||
data-test="choose-event-autocomplete"
|
data-test="choose-event-autocomplete"
|
||||||
|
componentsProps={{ popper: { className: 'nowheel' } }}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
@@ -240,6 +240,7 @@ function ChooseConnectionSubstep(props) {
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
loading={isAppConnectionsLoading}
|
loading={isAppConnectionsLoading}
|
||||||
data-test="choose-connection-autocomplete"
|
data-test="choose-connection-autocomplete"
|
||||||
|
componentsProps={{ popper: { className: 'nowheel' } }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@@ -32,9 +32,11 @@ function ControlledAutocomplete(props) {
|
|||||||
...autocompleteProps
|
...autocompleteProps
|
||||||
} = props;
|
} = props;
|
||||||
let dependsOnValues = [];
|
let dependsOnValues = [];
|
||||||
|
|
||||||
if (dependsOn?.length) {
|
if (dependsOn?.length) {
|
||||||
dependsOnValues = watch(dependsOn);
|
dependsOnValues = watch(dependsOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const hasDependencies = dependsOnValues.length;
|
const hasDependencies = dependsOnValues.length;
|
||||||
const allDepsSatisfied = dependsOnValues.every(Boolean);
|
const allDepsSatisfied = dependsOnValues.every(Boolean);
|
||||||
@@ -44,6 +46,7 @@ function ControlledAutocomplete(props) {
|
|||||||
resetField(name);
|
resetField(name);
|
||||||
}
|
}
|
||||||
}, dependsOnValues);
|
}, dependsOnValues);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Controller
|
||||||
rules={{ required }}
|
rules={{ required }}
|
||||||
|
@@ -47,6 +47,7 @@ const CustomOptions = (props) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
className="nowheel"
|
||||||
>
|
>
|
||||||
<Paper elevation={5} sx={{ width: '100%' }}>
|
<Paper elevation={5} sx={{ width: '100%' }}>
|
||||||
<Tabs
|
<Tabs
|
||||||
|
@@ -8,9 +8,11 @@ import { Stack } from '@mui/material';
|
|||||||
import { UPDATE_STEP } from 'graphql/mutations/update-step';
|
import { UPDATE_STEP } from 'graphql/mutations/update-step';
|
||||||
|
|
||||||
import { useAutoLayout } from './useAutoLayout';
|
import { useAutoLayout } from './useAutoLayout';
|
||||||
|
import { useScrollBoundries } from './useScrollBoundries';
|
||||||
import FlowStepNode from './FlowStepNode/FlowStepNode';
|
import FlowStepNode from './FlowStepNode/FlowStepNode';
|
||||||
import Edge from './Edge/Edge';
|
import Edge from './Edge/Edge';
|
||||||
import InvisibleNode from './InvisibleNode/InvisibleNode';
|
import InvisibleNode from './InvisibleNode/InvisibleNode';
|
||||||
|
import { EditorWrapper } from './style';
|
||||||
|
|
||||||
const nodeTypes = { flowStep: FlowStepNode, invisible: InvisibleNode };
|
const nodeTypes = { flowStep: FlowStepNode, invisible: InvisibleNode };
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ const EditorNew = ({ flow }) => {
|
|||||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||||
useAutoLayout();
|
useAutoLayout();
|
||||||
|
useScrollBoundries();
|
||||||
|
|
||||||
const onConnect = useCallback(
|
const onConnect = useCallback(
|
||||||
(params) => setEdges((eds) => addEdge(params, eds)),
|
(params) => setEdges((eds) => addEdge(params, eds)),
|
||||||
@@ -125,6 +128,7 @@ const EditorNew = ({ flow }) => {
|
|||||||
(flow, prevNodes) => {
|
(flow, prevNodes) => {
|
||||||
const newNodes = flow.steps.map((step, index) => {
|
const newNodes = flow.steps.map((step, index) => {
|
||||||
const node = prevNodes?.find(({ id }) => id === step.id);
|
const node = prevNodes?.find(({ id }) => id === step.id);
|
||||||
|
const collapsed = currentStepId !== step.id;
|
||||||
return {
|
return {
|
||||||
id: step.id,
|
id: step.id,
|
||||||
type: 'flowStep',
|
type: 'flowStep',
|
||||||
@@ -132,11 +136,12 @@ const EditorNew = ({ flow }) => {
|
|||||||
x: node ? node.position.x : 0,
|
x: node ? node.position.x : 0,
|
||||||
y: node ? node.position.y : 0,
|
y: node ? node.position.y : 0,
|
||||||
},
|
},
|
||||||
|
zIndex: collapsed ? 0 : 1,
|
||||||
data: {
|
data: {
|
||||||
step,
|
step,
|
||||||
index: index,
|
index: index,
|
||||||
flowId: flow.id,
|
flowId: flow.id,
|
||||||
collapsed: currentStepId !== step.id,
|
collapsed,
|
||||||
openNextStep: openNextStep(flow.steps[index + 1]),
|
openNextStep: openNextStep(flow.steps[index + 1]),
|
||||||
onOpen: () => setCurrentStepId(step.id),
|
onOpen: () => setCurrentStepId(step.id),
|
||||||
onClose: () => setCurrentStepId(null),
|
onClose: () => setCurrentStepId(null),
|
||||||
@@ -178,15 +183,31 @@ const EditorNew = ({ flow }) => {
|
|||||||
[setNodes],
|
[setNodes],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updateEdgesData = useCallback(
|
||||||
|
(flow) => {
|
||||||
|
setEdges((edges) =>
|
||||||
|
edges.map((edge) => {
|
||||||
|
return {
|
||||||
|
...edge,
|
||||||
|
data: { ...edge.data, flowId: flow.id, flowActive: flow.active },
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[setEdges],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNodes(
|
setNodes(
|
||||||
nodes.map((node) => {
|
nodes.map((node) => {
|
||||||
if (node.type === 'flowStep') {
|
if (node.type === 'flowStep') {
|
||||||
|
const collapsed = currentStepId !== node.data.step.id;
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
|
zIndex: collapsed ? 0 : 1,
|
||||||
data: {
|
data: {
|
||||||
...node.data,
|
...node.data,
|
||||||
collapsed: currentStepId !== node.data.step.id,
|
collapsed,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -204,19 +225,12 @@ const EditorNew = ({ flow }) => {
|
|||||||
setEdges(newEdges);
|
setEdges(newEdges);
|
||||||
} else {
|
} else {
|
||||||
updateNodesData(flow.steps);
|
updateNodesData(flow.steps);
|
||||||
|
updateEdgesData(flow);
|
||||||
}
|
}
|
||||||
}, [flow]);
|
}, [flow]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<EditorWrapper direction="column">
|
||||||
direction="column"
|
|
||||||
sx={{
|
|
||||||
flexGrow: 1,
|
|
||||||
'& > div': {
|
|
||||||
flexGrow: 1,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
@@ -233,7 +247,7 @@ const EditorNew = ({ flow }) => {
|
|||||||
zoomOnDoubleClick={false}
|
zoomOnDoubleClick={false}
|
||||||
panActivationKeyCode={null}
|
panActivationKeyCode={null}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</EditorWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -5,6 +5,8 @@ import PropTypes from 'prop-types';
|
|||||||
import FlowStep from 'components/FlowStep';
|
import FlowStep from 'components/FlowStep';
|
||||||
import { StepPropType } from 'propTypes/propTypes';
|
import { StepPropType } from 'propTypes/propTypes';
|
||||||
|
|
||||||
|
import { NodeWrapper, NodeInnerWrapper } from './style.js';
|
||||||
|
|
||||||
function FlowStepNode({
|
function FlowStepNode({
|
||||||
data: {
|
data: {
|
||||||
step,
|
step,
|
||||||
@@ -19,35 +21,37 @@ function FlowStepNode({
|
|||||||
},
|
},
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Box
|
<NodeWrapper
|
||||||
maxWidth={900}
|
|
||||||
width="100vw"
|
|
||||||
className="nodrag"
|
className="nodrag"
|
||||||
sx={{ visibility: layouted ? 'visible' : 'hidden' }}
|
sx={{
|
||||||
|
visibility: layouted ? 'visible' : 'hidden',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Handle
|
<NodeInnerWrapper>
|
||||||
type="target"
|
<Handle
|
||||||
position={Position.Top}
|
type="target"
|
||||||
isConnectable={false}
|
position={Position.Top}
|
||||||
style={{ visibility: 'hidden' }}
|
isConnectable={false}
|
||||||
/>
|
style={{ visibility: 'hidden' }}
|
||||||
<FlowStep
|
/>
|
||||||
step={step}
|
<FlowStep
|
||||||
index={index + 1}
|
step={step}
|
||||||
collapsed={collapsed}
|
index={index + 1}
|
||||||
onOpen={onOpen}
|
collapsed={collapsed}
|
||||||
onClose={onClose}
|
onOpen={onOpen}
|
||||||
onChange={onChange}
|
onClose={onClose}
|
||||||
flowId={flowId}
|
onChange={onChange}
|
||||||
onContinue={openNextStep}
|
flowId={flowId}
|
||||||
/>
|
onContinue={openNextStep}
|
||||||
<Handle
|
/>
|
||||||
type="source"
|
<Handle
|
||||||
position={Position.Bottom}
|
type="source"
|
||||||
isConnectable={false}
|
position={Position.Bottom}
|
||||||
style={{ visibility: 'hidden' }}
|
isConnectable={false}
|
||||||
/>
|
style={{ visibility: 'hidden' }}
|
||||||
</Box>
|
/>
|
||||||
|
</NodeInnerWrapper>
|
||||||
|
</NodeWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
packages/web/src/components/EditorNew/FlowStepNode/style.js
Normal file
14
packages/web/src/components/EditorNew/FlowStepNode/style.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import { Box } from '@mui/material';
|
||||||
|
|
||||||
|
export const NodeWrapper = styled(Box)(({ theme }) => ({
|
||||||
|
width: '100vw',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: theme.spacing(0, 2.5),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const NodeInnerWrapper = styled(Box)(({ theme }) => ({
|
||||||
|
maxWidth: 900,
|
||||||
|
flex: 1,
|
||||||
|
}));
|
@@ -10,19 +10,8 @@ function InvisibleNode() {
|
|||||||
className="nodrag"
|
className="nodrag"
|
||||||
sx={{ visibility: 'hidden' }}
|
sx={{ visibility: 'hidden' }}
|
||||||
>
|
>
|
||||||
<Handle
|
<Handle type="target" position={Position.Top} isConnectable={false} />
|
||||||
type="target"
|
|
||||||
position={Position.Top}
|
|
||||||
isConnectable={false}
|
|
||||||
style={{ visibility: 'hidden' }}
|
|
||||||
/>
|
|
||||||
Invisible node
|
Invisible node
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Bottom}
|
|
||||||
isConnectable={false}
|
|
||||||
style={{ visibility: 'hidden' }}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
13
packages/web/src/components/EditorNew/style.js
Normal file
13
packages/web/src/components/EditorNew/style.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
|
||||||
|
export const EditorWrapper = styled(Stack)(({ theme }) => ({
|
||||||
|
flexGrow: 1,
|
||||||
|
'& > div': {
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
'& .react-flow__pane, & .react-flow__node': {
|
||||||
|
cursor: 'auto !important',
|
||||||
|
},
|
||||||
|
}));
|
@@ -9,8 +9,6 @@ const getLayoutedElements = (nodes, edges) => {
|
|||||||
graph.setGraph({
|
graph.setGraph({
|
||||||
rankdir: 'TB',
|
rankdir: 'TB',
|
||||||
marginy: 60,
|
marginy: 60,
|
||||||
marginx: 60,
|
|
||||||
universalSep: true,
|
|
||||||
ranksep: 64,
|
ranksep: 64,
|
||||||
});
|
});
|
||||||
edges.forEach((edge) => graph.setEdge(edge.source, edge.target));
|
edges.forEach((edge) => graph.setEdge(edge.source, edge.target));
|
||||||
|
13
packages/web/src/components/EditorNew/useScrollBoundries.js
Normal file
13
packages/web/src/components/EditorNew/useScrollBoundries.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useViewport, useReactFlow } from 'reactflow';
|
||||||
|
|
||||||
|
export const useScrollBoundries = () => {
|
||||||
|
const { setViewport } = useReactFlow();
|
||||||
|
const { x, y, zoom } = useViewport();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (y > 0) {
|
||||||
|
setViewport({ x, y: 0, zoom });
|
||||||
|
}
|
||||||
|
}, [y]);
|
||||||
|
};
|
@@ -80,6 +80,7 @@ export default function InputCreator(props) {
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
showOptionValue={showOptionValue}
|
showOptionValue={showOptionValue}
|
||||||
shouldUnregister={shouldUnregister}
|
shouldUnregister={shouldUnregister}
|
||||||
|
componentsProps={{ popper: { className: 'nowheel' } }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@ import { StepExecutionsContext } from 'contexts/StepExecutions';
|
|||||||
import Popper from './Popper';
|
import Popper from './Popper';
|
||||||
import { processStepWithExecutions } from './data';
|
import { processStepWithExecutions } from './data';
|
||||||
import { ChildrenWrapper, FakeInput, InputLabelWrapper } from './style';
|
import { ChildrenWrapper, FakeInput, InputLabelWrapper } from './style';
|
||||||
|
|
||||||
const PowerInput = (props) => {
|
const PowerInput = (props) => {
|
||||||
const { control } = useFormContext();
|
const { control } = useFormContext();
|
||||||
const {
|
const {
|
||||||
@@ -31,33 +32,41 @@ const PowerInput = (props) => {
|
|||||||
} = props;
|
} = props;
|
||||||
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
|
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
|
||||||
const editorRef = React.useRef(null);
|
const editorRef = React.useRef(null);
|
||||||
|
|
||||||
const renderElement = React.useCallback(
|
const renderElement = React.useCallback(
|
||||||
(props) => <Element {...props} />,
|
(props) => <Element {...props} />,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [editor] = React.useState(() => customizeEditor(createEditor()));
|
const [editor] = React.useState(() => customizeEditor(createEditor()));
|
||||||
|
|
||||||
const [showVariableSuggestions, setShowVariableSuggestions] =
|
const [showVariableSuggestions, setShowVariableSuggestions] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
|
|
||||||
const disappearSuggestionsOnShift = (event) => {
|
const disappearSuggestionsOnShift = (event) => {
|
||||||
if (event.code === 'Tab') {
|
if (event.code === 'Tab') {
|
||||||
setShowVariableSuggestions(false);
|
setShowVariableSuggestions(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stepsWithVariables = React.useMemo(() => {
|
const stepsWithVariables = React.useMemo(() => {
|
||||||
return processStepWithExecutions(priorStepsWithExecutions);
|
return processStepWithExecutions(priorStepsWithExecutions);
|
||||||
}, [priorStepsWithExecutions]);
|
}, [priorStepsWithExecutions]);
|
||||||
|
|
||||||
const handleBlur = React.useCallback(
|
const handleBlur = React.useCallback(
|
||||||
(value) => {
|
(value) => {
|
||||||
onBlur?.(value);
|
onBlur?.(value);
|
||||||
},
|
},
|
||||||
[onBlur],
|
[onBlur],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleVariableSuggestionClick = React.useCallback(
|
const handleVariableSuggestionClick = React.useCallback(
|
||||||
(variable) => {
|
(variable) => {
|
||||||
insertVariable(editor, variable, stepsWithVariables);
|
insertVariable(editor, variable, stepsWithVariables);
|
||||||
},
|
},
|
||||||
[stepsWithVariables],
|
[stepsWithVariables],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Controller
|
||||||
rules={{ required }}
|
rules={{ required }}
|
||||||
@@ -127,6 +136,7 @@ const PowerInput = (props) => {
|
|||||||
anchorEl={editorRef.current}
|
anchorEl={editorRef.current}
|
||||||
data={stepsWithVariables}
|
data={stepsWithVariables}
|
||||||
onSuggestionClick={handleVariableSuggestionClick}
|
onSuggestionClick={handleVariableSuggestionClick}
|
||||||
|
className="nowheel"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormHelperText variant="outlined">{description}</FormHelperText>
|
<FormHelperText variant="outlined">{description}</FormHelperText>
|
||||||
|
Reference in New Issue
Block a user