Browse Source

refactor: use layout to avoid flowChart being undefined

master
smallstonesk 4 years ago
parent
commit
0ef34c1c22
  1. 22
      packages/core/src/index.module.less
  2. 22
      packages/core/src/index.tsx
  3. 15
      packages/core/src/mods/header/connectStatus/index.tsx
  4. 7
      packages/core/src/mods/header/index.module.less
  5. 2
      packages/core/src/mods/header/index.tsx
  6. 44
      packages/core/src/mods/layout/index.module.less
  7. 54
      packages/core/src/mods/layout/index.tsx
  8. 3
      packages/core/src/mods/settingBar/index.module.less
  9. 51
      packages/core/src/mods/settingBar/index.tsx
  10. 3
      packages/core/src/mods/sideBar/index.module.less
  11. 23
      packages/core/src/mods/sideBar/index.tsx
  12. 5
      packages/core/src/mods/toolBar/index.module.less
  13. 15
      packages/core/src/mods/toolBar/index.tsx

22
packages/core/src/index.module.less

@ -1,22 +0,0 @@
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
.body {
flex: 1;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
.full {
flex: 1;
display: flex;
flex-direction: column;
}
}
}

22
packages/core/src/index.tsx

@ -1,9 +1,9 @@
import React, {useState} from 'react'; import React, {useState} from 'react';
import '@antv/x6/dist/x6.css'; import '@antv/x6/dist/x6.css';
import styles from './index.module.less';
import {Graph} from '@antv/x6'; import {Graph} from '@antv/x6';
import Layout from './mods/layout';
import Header from './mods/header'; import Header from './mods/header';
import SideBar from './mods/sideBar'; import SideBar from './mods/sideBar';
import ToolBar from './mods/toolBar'; import ToolBar from './mods/toolBar';
@ -32,17 +32,15 @@ const Core: React.FC<IProps> = props => {
}; };
return ( return (
<div className={styles.container}> <Layout
<Header flowChart={flowChart}/> flowChart={flowChart}
<div className={styles.body}> Header={Header}
<SideBar flowChart={flowChart}/> SideBar={SideBar}
<div className={styles.full}> ToolBar={ToolBar}
<ToolBar flowChart={flowChart}/> SettingBar={SettingBar}
<FlowChart onReady={onFlowChartReady}/> >
</div> <FlowChart onReady={onFlowChartReady}/>
<SettingBar flowChart={flowChart}/> </Layout>
</div>
</div>
); );
}; };

15
packages/core/src/mods/header/connectStatus/index.tsx

@ -16,7 +16,7 @@ enum Status {
} }
interface IProps { interface IProps {
flowChart: Graph | undefined; flowChart: Graph;
} }
const PULSE_RATE = 10 * 1000; // try to connect to local servet per 10 seconds const PULSE_RATE = 10 * 1000; // try to connect to local servet per 10 seconds
@ -30,12 +30,10 @@ const ConnectStatus: React.FC<IProps> = (props) => {
// life // life
useEffect(() => { useEffect(() => {
if(flowChart) { confirmToSync();
confirmToSync(); const timer = setInterval(syncLocal, PULSE_RATE);
const timer = setInterval(syncLocal, PULSE_RATE); return () => clearInterval(timer);
return () => clearInterval(timer); }, []);
}
}, [flowChart]);
// network // network
const syncLocal = () => { const syncLocal = () => {
@ -56,8 +54,7 @@ const ConnectStatus: React.FC<IProps> = (props) => {
title: '本地连接成功,是否将数据同步至当前项目?', title: '本地连接成功,是否将数据同步至当前项目?',
onOk() { onOk() {
try { try {
console.log(props.flowChart); flowChart.fromJSON(dsl);
flowChart && flowChart.fromJSON(dsl);
} catch(err) { } catch(err) {
message.error('同步失败!'); message.error('同步失败!');
} }

7
packages/core/src/mods/header/index.module.less

@ -1,11 +1,12 @@
.container { .container {
flex: 1;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
height: 48px; align-items: center;
line-height: 48px; width: 100%;
height: 100%;
background-color: #FEFEFE; background-color: #FEFEFE;
border-bottom: 1px solid #D9D9D9;
} }
.titleText { .titleText {

2
packages/core/src/mods/header/index.tsx

@ -6,7 +6,7 @@ import {Graph} from '@antv/x6';
import ConnectStatus from './connectStatus'; import ConnectStatus from './connectStatus';
interface IProps { interface IProps {
flowChart: Graph | undefined; flowChart: Graph;
} }
const Header: React.FC<IProps> = props => { const Header: React.FC<IProps> = props => {

44
packages/core/src/mods/layout/index.module.less

@ -0,0 +1,44 @@
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
.header {
width: 100%;
height: 48px;
border-bottom: 1px solid #D9D9D9;
}
.body {
flex: 1;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
.sideBar {
width: 235px;
border-right: 1px solid #D9D9D9;
}
.full {
flex: 1;
display: flex;
flex-direction: column;
.toolBar {
height: 43px;
}
}
.settingBar {
width: 350px;
height: 100%;
border-left: 1px solid #D9D9D9;
}
}
}

54
packages/core/src/mods/layout/index.tsx

@ -0,0 +1,54 @@
import React from 'react';
import styles from './index.module.less';
import {Graph} from '@antv/x6';
interface ISubComponentProps {
flowChart: Graph;
}
interface IProps {
flowChart: Graph | undefined;
Header: React.FC<ISubComponentProps>;
SideBar: React.FC<ISubComponentProps>;
ToolBar: React.FC<ISubComponentProps>;
SettingBar: React.FC<ISubComponentProps>;
}
const Layout: React.FC<IProps> = (props) => {
const {flowChart, Header, SideBar, ToolBar, SettingBar} = props;
let header, sideBar, toolBar, settingBar;
if(flowChart) {
header = <Header flowChart={flowChart}/>;
sideBar = <SideBar flowChart={flowChart}/>;
toolBar = <ToolBar flowChart={flowChart}/>;
settingBar = <SettingBar flowChart={flowChart}/>;
}
return (
<div className={styles.container}>
<div className={styles.header}>
{header}
</div>
<div className={styles.body}>
<div className={styles.sideBar}>
{sideBar}
</div>
<div className={styles.full}>
<div className={styles.toolBar}>
{toolBar}
</div>
{props.children}
</div>
<div className={styles.settingBar}>
{settingBar}
</div>
</div>
</div>
);
};
export default Layout;

3
packages/core/src/mods/settingBar/index.module.less

@ -2,9 +2,8 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 350px; width: 100%;
height: 100%; height: 100%;
border-left: 1px solid #D9D9D9;
&.center { &.center {
justify-content: center; justify-content: center;

51
packages/core/src/mods/settingBar/index.tsx

@ -12,46 +12,41 @@ import {Graph} from '@antv/x6';
const {TabPane} = Tabs; const {TabPane} = Tabs;
interface IProps { interface IProps {
flowChart: Graph | undefined; flowChart: Graph;
} }
const SettingBar: React.FC<IProps> = props => { const SettingBar: React.FC<IProps> = props => {
const {flowChart} = props; const {flowChart} = props;
const [ignored, forceUpdate] = useReducer(n => n + 1, 0); const forceUpdate = useReducer(n => n + 1, 0)[1];
useEffect(() => { useEffect(() => {
flowChart && flowChart.on('settingBar:forceUpdate', forceUpdate); flowChart.on('settingBar:forceUpdate', forceUpdate);
return () => { return () => {
flowChart && flowChart.off('settingBar:forceUpdate'); flowChart.off('settingBar:forceUpdate');
}; };
}, [flowChart]); }, []);
if(!flowChart) {
const nodes = flowChart.getSelectedCells().filter(v => v.shape !== 'edge');
if(nodes.length === 1) {
return (
<div className={styles.container}>
<Tabs tabBarGutter={0} defaultActiveKey={'basic'} tabBarStyle={{display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<TabPane tab={'基础信息'} key={'basic'}>
<Basic selectedCell={nodes[0]}/>
</TabPane>
<TabPane tab={'投放配置'} key={'config'}>
<Config selectedCell={nodes[0]}/>
</TabPane>
</Tabs>
</div>
);
} else {
return ( return (
<div className={`${styles.container} ${styles.center}`}> <div className={`${styles.container} ${styles.center}`}>
<Empty description={'请选择一个节点'} image={Empty.PRESENTED_IMAGE_SIMPLE}/> <Empty description={'请选择一个节点'} image={Empty.PRESENTED_IMAGE_SIMPLE}/>
</div> </div>
); );
} else {
const nodes = flowChart.getSelectedCells().filter(v => v.shape !== 'edge');
if(nodes.length === 1) {
return (
<div className={styles.container}>
<Tabs tabBarGutter={0} defaultActiveKey={'basic'} tabBarStyle={{display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<TabPane tab={'基础信息'} key={'basic'}>
<Basic selectedCell={nodes[0]}/>
</TabPane>
<TabPane tab={'投放配置'} key={'config'}>
<Config selectedCell={nodes[0]}/>
</TabPane>
</Tabs>
</div>
);
} else {
return (
<div className={`${styles.container} ${styles.center}`}>
<Empty description={'请选择一个节点'} image={Empty.PRESENTED_IMAGE_SIMPLE}/>
</div>
);
}
} }
}; };

3
packages/core/src/mods/sideBar/index.module.less

@ -1,7 +1,6 @@
.container { .container {
width: 235px; width: 100%;
border-right: 1px solid #D9D9D9;
:global { :global {
.ant-collapse > .ant-collapse-item > .ant-collapse-header { .ant-collapse > .ant-collapse-item > .ant-collapse-header {

23
packages/core/src/mods/sideBar/index.tsx

@ -28,11 +28,11 @@ interface IGroupItem {
cells: string[]; cells: string[];
} }
interface ISideBarPorps { interface ISideBarProps {
flowChart: Graph | undefined; flowChart: Graph;
} }
const SideBar: React.FC<ISideBarPorps> = props => { const SideBar: React.FC<ISideBarProps> = props => {
const {flowChart} = props; const {flowChart} = props;
const [dnd, setDnd] = useState<Addon.Dnd>(); const [dnd, setDnd] = useState<Addon.Dnd>();
@ -42,20 +42,16 @@ const SideBar: React.FC<ISideBarPorps> = props => {
useEffect(() => { useEffect(() => {
// TODO: fetch to get custom group data // TODO: fetch to get custom group data
setGroups([GENERAL_GROUP]); setGroups([GENERAL_GROUP]);
setDnd(new Dnd({target: flowChart, scaled: true}));
}, []); }, []);
useEffect(() => {
if(flowChart) {
setDnd(new Dnd({target: flowChart, scaled: true}));
}
}, [flowChart]);
return ( return (
<div className={styles.container}> <div className={styles.container}>
{flowChart && dnd && ( {dnd && (
<Collapse className={styles.collapse} defaultActiveKey={['general', 'custom']}> <Collapse className={styles.collapse} defaultActiveKey={['general', 'custom']}>
{groups.map(group => ( {groups.map(group => (
<Panel key={group.key} header={group.name}> <Panel key={group.key} header={group.name}>
<PanelContent dnd={dnd} cells={group.cells} flowChart={flowChart}/> <PanelContent dnd={dnd} cells={group.cells}/>
</Panel> </Panel>
))} ))}
</Collapse> </Collapse>
@ -67,14 +63,13 @@ const SideBar: React.FC<ISideBarPorps> = props => {
interface IPanelContentProps { interface IPanelContentProps {
dnd: Addon.Dnd; dnd: Addon.Dnd;
cells: string[]; cells: string[];
flowChart: Graph;
} }
const PanelContent: React.FC<IPanelContentProps> = props => { const PanelContent: React.FC<IPanelContentProps> = props => {
const {dnd, cells, flowChart} = props; const {dnd, cells} = props;
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
if(ref.current && flowChart) { if(ref.current) {
const graph = new Graph({ const graph = new Graph({
container: ref.current, container: ref.current,
width: ref.current.offsetWidth, width: ref.current.offsetWidth,
@ -102,7 +97,7 @@ const PanelContent: React.FC<IPanelContentProps> = props => {
dnd.start(newNode, e); dnd.start(newNode, e);
}); });
} }
}, [flowChart]); }, []);
return <div className={styles.chart} ref={ref}/>; return <div className={styles.chart} ref={ref}/>;
}; };

5
packages/core/src/mods/toolBar/index.module.less

@ -4,7 +4,8 @@
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
height: 43px; width: 100%;
height: 100%;
background-color: #FAFAFA; background-color: #FAFAFA;
border-bottom: 1px solid #D9D9D9; border-bottom: 1px solid #D9D9D9;
@ -13,7 +14,7 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
padding: 0 4px; padding: 0 4px;
height: 43px; height: 100%;
border-right: 1px solid #D9D9D9; border-right: 1px solid #D9D9D9;
} }
} }

15
packages/core/src/mods/toolBar/index.tsx

@ -7,21 +7,24 @@ import {Graph} from '@antv/x6';
import widgets from './widgets'; import widgets from './widgets';
interface IProps { interface IProps {
flowChart: Graph | undefined; flowChart: Graph;
} }
const ToolBar: React.FC<IProps> = props => { const ToolBar: React.FC<IProps> = props => {
const {flowChart} = props; const {flowChart} = props;
const [ignored, forceUpdate] = useReducer(n => n + 1, 0); const forceUpdate = useReducer(n => n + 1, 0)[1];
useEffect(() => { useEffect(() => {
flowChart && flowChart.on('toolBar:forceUpdate', forceUpdate); flowChart.on('toolBar:forceUpdate', forceUpdate);
return () => { return () => {
flowChart && flowChart.off('toolBar:forceUpdate'); flowChart.off('toolBar:forceUpdate');
}; };
}, [flowChart]); }, []);
return ( return (
<div className={styles.container}> <div className={styles.container}>
{flowChart && widgets.map((group, index) => ( {widgets.map((group, index) => (
<div key={index} className={styles.group}> <div key={index} className={styles.group}>
{group.map((ToolItem, index) => { {group.map((ToolItem, index) => {
return <ToolItem key={index} flowChart={flowChart}/>; return <ToolItem key={index} flowChart={flowChart}/>;

Loading…
Cancel
Save