import { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import invariant from 'invariant'; import get from 'lodash/get'; import { Map } from 'immutable'; import { setZoom } from '../actions/flow.actions'; import Grid from './grid/Grid.component'; import ZoomHandler from './ZoomHandler.component'; import NodesRenderer from './node/NodesRenderer.component'; import LinksRenderer from './link/LinksRenderer.component'; import PortsRenderer from './port/PortsRenderer.component'; import { startMoveNodeTo, moveNodeTo, moveNodeToEnd } from '../actions/node.actions'; import { setNodeTypes } from '../actions/nodeType.actions'; import { Transform, NodeRecordMap, PortRecordMap, LinkRecordMap, Position, Id, } from '../customTypings/index.d'; type Props = { children?: any; setNodeTypes: (nodeTypeMap: StateMap) => void; startMoveNodeTo: (nodeId: Id, nodePosition: string) => void; moveNodeTo: (nodeId: Id, nodePosition: Position) => void; moveNodeToEnd: (nodeId: Id, nodePosition: Position) => void; nodes: NodeRecordMap; ports: PortRecordMap; links: LinkRecordMap; reduxMountPoint: string; onClick?: () => {}; transform?: Transform; transformToApply?: Transform; setZoom?: (transform: Transform) => void; snapToGrid?: boolean; }; type StateMap = { [key: string]: any }; type State = { nodeTypeMap: StateMap; linkTypeMap: StateMap; portTypeMap: StateMap; }; export function FlowDesigner(props: Props) { const [state, setState] = useState(() => { const nodeTypeMap: StateMap = {}; const linkTypeMap: StateMap = {}; const portTypeMap: StateMap = {}; const { children } = props; if (children) { (children as any).forEach( (element: { type: { displayName: string }; props: { component: any; type: string } }) => { switch (element.type.displayName) { case 'NodeType': nodeTypeMap[element.props.type] = { component: element.props.component }; break; case 'LinkType': linkTypeMap[element.props.type] = { component: element.props.component }; break; case 'PortType': portTypeMap[element.props.type] = { component: element.props.component }; break; default: invariant( false, `<${element.type.displayName} /> is an unknown component configuration`, ); } }, ); } else { invariant(false, ' should have configuration component as child'); } return { nodeTypeMap, linkTypeMap, portTypeMap }; }); useEffect(() => { props.setNodeTypes(state.nodeTypeMap); }, []); return ( ); } const mapStateToProps = (state: State, ownProps: Props) => ({ nodes: get(state, ownProps.reduxMountPoint).get('nodes'), links: get(state, ownProps.reduxMountPoint).get('links'), ports: get(state, ownProps.reduxMountPoint).get('ports'), transform: get(state, ownProps.reduxMountPoint).get('transform'), transformToApply: get(state, ownProps.reduxMountPoint).get('transformToApply'), }); const mapDispatchToProps = (dispatch: any) => ({ setNodeTypes: (nodeTypeMap: Map) => dispatch(setNodeTypes(nodeTypeMap)), startMoveNodeTo: (nodeId: Id, nodePosition: string) => dispatch(startMoveNodeTo(nodeId, nodePosition)), moveNodeTo: (nodeId: Id, nodePosition: Position) => dispatch(moveNodeTo(nodeId, nodePosition)), moveNodeToEnd: (nodeId: Id, nodePosition: Position) => dispatch(moveNodeToEnd(nodeId, nodePosition)), setZoom: (transform: Transform) => dispatch(setZoom(transform)), }); const connector: any = connect(mapStateToProps, mapDispatchToProps); export default connector(FlowDesigner);