Update formatting
This commit is contained in:
parent
86b3cec1e7
commit
15a86e4830
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"printWidth": 100,
|
||||
"parser": "babylon",
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2
|
||||
}
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
"start:client": "cd src/public && webpack --progress --colors --watch --env dev",
|
||||
"start:server": "nodemon ./src/server/index.js",
|
||||
"start:server-debug": "nodemon --inspect ./src/server/index.js",
|
||||
"start:demo": "node ./src/server/index.js"
|
||||
"start:demo": "node ./src/server/index.js",
|
||||
"pretty": "prettier --write \"./src/public/js/**/*.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"antd": "^3.5.0",
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
"devDependencies": {
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"nodemon": "^1.17.3",
|
||||
"prettier": "^1.14.0",
|
||||
"webpack-cli": "^2.1.2"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -8,26 +8,23 @@ import SideBar from './components/side-bar/SideBarContainer';
|
|||
import './App.css';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div className="App-container">
|
||||
<header className="App-header">
|
||||
<DataBus />
|
||||
<ViewsSwitches />
|
||||
</header>
|
||||
return (
|
||||
<div className="App-container">
|
||||
<header className="App-header">
|
||||
<DataBus />
|
||||
<ViewsSwitches />
|
||||
</header>
|
||||
|
||||
<div className="App-body">
|
||||
<TreeDiagram />
|
||||
<SideBar />
|
||||
</div>
|
||||
<div className="App-body">
|
||||
<TreeDiagram />
|
||||
<SideBar />
|
||||
</div>
|
||||
|
||||
<footer className="App-footer">
|
||||
Bohdan Liashenko{' '}
|
||||
<a href="https://github.com/Bogdan-Lyashenko/codecrumbs">
|
||||
Project Github
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
<footer className="App-footer">
|
||||
Bohdan Liashenko <a href="https://github.com/Bogdan-Lyashenko/codecrumbs">Project Github</a>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -4,14 +4,17 @@ import { toggleSwitch, fireButtonAction } from './store/actions';
|
|||
import { CONTROLS_KEYS } from './store/constants';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { switches, checkedState, disabledState } = state.viewSwitches;
|
||||
const { switches, checkedState, disabledState } = state.viewSwitches;
|
||||
|
||||
return { switches, checkedState, disabledState };
|
||||
return { switches, checkedState, disabledState };
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
toggleSwitch,
|
||||
fireButtonAction
|
||||
toggleSwitch,
|
||||
fireButtonAction
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ViewSwitchList);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ViewSwitchList);
|
||||
|
|
|
|||
|
|
@ -4,77 +4,65 @@ import './ViewSwitchList.css';
|
|||
import { VIEW_TYPES } from '../store/constants';
|
||||
|
||||
class ViewsSwitchList extends React.Component {
|
||||
renderChildren(controls) {
|
||||
const {
|
||||
toggleSwitch,
|
||||
checkedState,
|
||||
disabledState,
|
||||
fireButtonAction
|
||||
} = this.props;
|
||||
renderChildren(controls) {
|
||||
const { toggleSwitch, checkedState, disabledState, fireButtonAction } = this.props;
|
||||
|
||||
return (
|
||||
<div className="ViewSwitchList-small-group">
|
||||
{controls.map((item, i) => {
|
||||
return (
|
||||
<div
|
||||
key={item.key}
|
||||
className="ViewSwitchList-small-item"
|
||||
>
|
||||
{item.type === VIEW_TYPES.BUTTON ? (
|
||||
<Button
|
||||
title={item.title}
|
||||
size={'small'}
|
||||
disabled={disabledState[item.key]}
|
||||
onClick={() => fireButtonAction(item.key)}
|
||||
>
|
||||
<span title={item.title}>{item.name}</span>
|
||||
</Button>
|
||||
) : (
|
||||
<Checkbox
|
||||
checked={checkedState[item.key]}
|
||||
onChange={e =>
|
||||
toggleSwitch(item.key, e.target.checked)
|
||||
}
|
||||
>
|
||||
<span title={item.title}>{item.name}</span>
|
||||
</Checkbox>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<div className="ViewSwitchList-small-group">
|
||||
{controls.map((item, i) => {
|
||||
return (
|
||||
<div key={item.key} className="ViewSwitchList-small-item">
|
||||
{item.type === VIEW_TYPES.BUTTON ? (
|
||||
<Button
|
||||
title={item.title}
|
||||
size={'small'}
|
||||
disabled={disabledState[item.key]}
|
||||
onClick={() => fireButtonAction(item.key)}
|
||||
>
|
||||
<span title={item.title}>{item.name}</span>
|
||||
</Button>
|
||||
) : (
|
||||
<Checkbox
|
||||
checked={checkedState[item.key]}
|
||||
onChange={e => toggleSwitch(item.key, e.target.checked)}
|
||||
>
|
||||
<span title={item.title}>{item.name}</span>
|
||||
</Checkbox>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { switches, toggleSwitch, checkedState } = this.props;
|
||||
render() {
|
||||
const { switches, toggleSwitch, checkedState } = this.props;
|
||||
|
||||
return (
|
||||
<div className="ViewSwitchList-container">
|
||||
{switches.map((item, i) => {
|
||||
return (
|
||||
<div className="ViewSwitchList-group" key={item.key}>
|
||||
<div className="ViewSwitchList-big-item">
|
||||
<span>{item.name + ' '}</span>
|
||||
<Switch
|
||||
size="small"
|
||||
checked={checkedState[item.key]}
|
||||
onChange={checked =>
|
||||
toggleSwitch(item.key, checked)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
return (
|
||||
<div className="ViewSwitchList-container">
|
||||
{switches.map((item, i) => {
|
||||
return (
|
||||
<div className="ViewSwitchList-group" key={item.key}>
|
||||
<div className="ViewSwitchList-big-item">
|
||||
<span>{item.name + ' '}</span>
|
||||
<Switch
|
||||
size="small"
|
||||
checked={checkedState[item.key]}
|
||||
onChange={checked => toggleSwitch(item.key, checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{(checkedState[item.key] &&
|
||||
item.children.length &&
|
||||
this.renderChildren(item.children)) ||
|
||||
null}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{(checkedState[item.key] &&
|
||||
item.children.length &&
|
||||
this.renderChildren(item.children)) ||
|
||||
null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ViewsSwitchList;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import { ACTIONS } from './constants';
|
||||
|
||||
export const toggleSwitch = (switchKey, checked) => ({
|
||||
type: ACTIONS.TOGGLE_SWITCH,
|
||||
payload: { switchKey, checked }
|
||||
type: ACTIONS.TOGGLE_SWITCH,
|
||||
payload: { switchKey, checked }
|
||||
});
|
||||
|
||||
export const fireButtonAction = buttonKey => ({
|
||||
type: ACTIONS.FIRE_BUTTON_ACTION,
|
||||
payload: buttonKey
|
||||
type: ACTIONS.FIRE_BUTTON_ACTION,
|
||||
payload: buttonKey
|
||||
});
|
||||
|
||||
export const setDisabledControl = (controlKey, disabled) => ({
|
||||
type: ACTIONS.SET_DISABLED_CONTROL,
|
||||
payload: { controlKey, disabled }
|
||||
type: ACTIONS.SET_DISABLED_CONTROL,
|
||||
payload: { controlKey, disabled }
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
export const ACTIONS = {
|
||||
TOGGLE_SWITCH: 'SWITCHES_LIST.TOGGLE_SWITCH',
|
||||
FIRE_BUTTON_ACTION: 'SWITCHES_LIST.FIRE_BUTTON_ACTION',
|
||||
SET_DISABLED_CONTROL: 'SWITCHES_LIST.SET_DISABLED_CONTROL'
|
||||
TOGGLE_SWITCH: 'SWITCHES_LIST.TOGGLE_SWITCH',
|
||||
FIRE_BUTTON_ACTION: 'SWITCHES_LIST.FIRE_BUTTON_ACTION',
|
||||
SET_DISABLED_CONTROL: 'SWITCHES_LIST.SET_DISABLED_CONTROL'
|
||||
};
|
||||
|
||||
export const CONTROLS_KEYS = {
|
||||
SOURCE: 'source',
|
||||
SOURCE_COLLAPSE_TO_MIN: 'sourceCollapseToMin',
|
||||
SOURCE_EXPAND_ALL: 'sourceExpandAll',
|
||||
DEPENDENCIES: 'dependencies',
|
||||
DEPENDENCIES_SHOW_ALL: 'dependenciesShowAll',
|
||||
DEPENDENCIES_SHOW_ONE_MODULE: 'dependenciesShowOneModule',
|
||||
CODE_CRUMBS: 'codeCrumbs',
|
||||
CODE_CRUMBS_MINIMIZE: 'codeCrumbsMinimize',
|
||||
CODE_CRUMBS_DETAILS: 'codeCrumbsDetails'
|
||||
SOURCE: 'source',
|
||||
SOURCE_COLLAPSE_TO_MIN: 'sourceCollapseToMin',
|
||||
SOURCE_EXPAND_ALL: 'sourceExpandAll',
|
||||
DEPENDENCIES: 'dependencies',
|
||||
DEPENDENCIES_SHOW_ALL: 'dependenciesShowAll',
|
||||
DEPENDENCIES_SHOW_ONE_MODULE: 'dependenciesShowOneModule',
|
||||
CODE_CRUMBS: 'codeCrumbs',
|
||||
CODE_CRUMBS_MINIMIZE: 'codeCrumbsMinimize',
|
||||
CODE_CRUMBS_DETAILS: 'codeCrumbsDetails'
|
||||
};
|
||||
|
||||
export const VIEW_TYPES = {
|
||||
BUTTON: 'icon'
|
||||
BUTTON: 'icon'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,106 +1,106 @@
|
|||
import { ACTIONS, CONTROLS_KEYS, VIEW_TYPES } from './constants';
|
||||
|
||||
const DefaultState = {
|
||||
switches: [
|
||||
switches: [
|
||||
{
|
||||
name: 'Source',
|
||||
key: CONTROLS_KEYS.SOURCE,
|
||||
children: [
|
||||
{
|
||||
name: 'Source',
|
||||
key: CONTROLS_KEYS.SOURCE,
|
||||
children: [
|
||||
{
|
||||
name: 'close all',
|
||||
title: 'Close folders to 2nd Level',
|
||||
key: CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
},
|
||||
{
|
||||
name: 'open all',
|
||||
title: 'Open all folders',
|
||||
key: CONTROLS_KEYS.SOURCE_EXPAND_ALL,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
}
|
||||
]
|
||||
name: 'close all',
|
||||
title: 'Close folders to 2nd Level',
|
||||
key: CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
},
|
||||
{
|
||||
name: 'Dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES,
|
||||
children: [
|
||||
{
|
||||
name: 'show all',
|
||||
title: 'Show All dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
},
|
||||
{
|
||||
name: 'direct only',
|
||||
title: 'Show One module dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'CodeCrumbs',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS,
|
||||
children: [
|
||||
{
|
||||
name: 'minimize',
|
||||
title: 'Minimize code crumbs',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS_MINIMIZE
|
||||
},
|
||||
{
|
||||
name: 'show details',
|
||||
title: 'Show all Details',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS_DETAILS
|
||||
}
|
||||
]
|
||||
name: 'open all',
|
||||
title: 'Open all folders',
|
||||
key: CONTROLS_KEYS.SOURCE_EXPAND_ALL,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
}
|
||||
],
|
||||
checkedState: {
|
||||
[CONTROLS_KEYS.SOURCE]: true
|
||||
]
|
||||
},
|
||||
disabledState: {
|
||||
[CONTROLS_KEYS.SOURCE_EXPAND_ALL]: true,
|
||||
[CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL]: true
|
||||
{
|
||||
name: 'Dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES,
|
||||
children: [
|
||||
{
|
||||
name: 'show all',
|
||||
title: 'Show All dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL,
|
||||
type: VIEW_TYPES.BUTTON
|
||||
},
|
||||
{
|
||||
name: 'direct only',
|
||||
title: 'Show One module dependencies',
|
||||
key: CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'CodeCrumbs',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS,
|
||||
children: [
|
||||
{
|
||||
name: 'minimize',
|
||||
title: 'Minimize code crumbs',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS_MINIMIZE
|
||||
},
|
||||
{
|
||||
name: 'show details',
|
||||
title: 'Show all Details',
|
||||
key: CONTROLS_KEYS.CODE_CRUMBS_DETAILS
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
checkedState: {
|
||||
[CONTROLS_KEYS.SOURCE]: true
|
||||
},
|
||||
disabledState: {
|
||||
[CONTROLS_KEYS.SOURCE_EXPAND_ALL]: true,
|
||||
[CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL]: true
|
||||
}
|
||||
};
|
||||
|
||||
export default (state = DefaultState, action) => {
|
||||
switch (action.type) {
|
||||
case ACTIONS.TOGGLE_SWITCH:
|
||||
const { switchKey, checked } = action.payload;
|
||||
switch (action.type) {
|
||||
case ACTIONS.TOGGLE_SWITCH:
|
||||
const { switchKey, checked } = action.payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
checkedState: {
|
||||
...state.checkedState,
|
||||
[switchKey]: checked
|
||||
}
|
||||
};
|
||||
break;
|
||||
return {
|
||||
...state,
|
||||
checkedState: {
|
||||
...state.checkedState,
|
||||
[switchKey]: checked
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
case ACTIONS.FIRE_BUTTON_ACTION:
|
||||
const buttonKey = action.payload;
|
||||
case ACTIONS.FIRE_BUTTON_ACTION:
|
||||
const buttonKey = action.payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
disabledState: {
|
||||
...state.disabledState,
|
||||
[buttonKey]: true
|
||||
}
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
disabledState: {
|
||||
...state.disabledState,
|
||||
[buttonKey]: true
|
||||
}
|
||||
};
|
||||
|
||||
case ACTIONS.SET_DISABLED_CONTROL:
|
||||
const { controlKey, disabled } = action.payload;
|
||||
case ACTIONS.SET_DISABLED_CONTROL:
|
||||
const { controlKey, disabled } = action.payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
disabledState: {
|
||||
...state.disabledState,
|
||||
[controlKey]: disabled
|
||||
}
|
||||
};
|
||||
break;
|
||||
return {
|
||||
...state,
|
||||
disabledState: {
|
||||
...state.disabledState,
|
||||
[controlKey]: disabled
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,47 +3,44 @@ import { connect } from 'react-redux';
|
|||
|
||||
import { createConnection } from '../../utils/connection';
|
||||
import { SOCKET_EVENT_TYPE } from '../../../../shared/constants';
|
||||
import {
|
||||
setInitialSourceData,
|
||||
calcFilesTreeLayoutNodes
|
||||
} from './store/actions';
|
||||
import { setInitialSourceData, calcFilesTreeLayoutNodes } from './store/actions';
|
||||
|
||||
class DataBusContainer extends React.Component {
|
||||
componentDidMount() {
|
||||
createConnection(({ type, data }) => this.onSocketEvent(type, data));
|
||||
componentDidMount() {
|
||||
createConnection(({ type, data }) => this.onSocketEvent(type, data));
|
||||
}
|
||||
|
||||
onSocketEvent(type, data) {
|
||||
switch (type) {
|
||||
case SOCKET_EVENT_TYPE.SYNC_SOURCE_FILES:
|
||||
const { filesTree, filesList, dependenciesList } = data.body;
|
||||
const { setInitialSourceData, calcFilesTreeLayoutNodes } = this.props;
|
||||
|
||||
setInitialSourceData({
|
||||
filesTree,
|
||||
filesList,
|
||||
dependenciesList
|
||||
});
|
||||
|
||||
calcFilesTreeLayoutNodes();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onSocketEvent(type, data) {
|
||||
switch (type) {
|
||||
case SOCKET_EVENT_TYPE.SYNC_SOURCE_FILES:
|
||||
const { filesTree, filesList, dependenciesList } = data.body;
|
||||
const {
|
||||
setInitialSourceData,
|
||||
calcFilesTreeLayoutNodes
|
||||
} = this.props;
|
||||
|
||||
setInitialSourceData({
|
||||
filesTree,
|
||||
filesList,
|
||||
dependenciesList
|
||||
});
|
||||
|
||||
calcFilesTreeLayoutNodes();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="DataBus-container" />;
|
||||
}
|
||||
render() {
|
||||
return <div className="DataBus-container" />;
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setInitialSourceData,
|
||||
calcFilesTreeLayoutNodes
|
||||
setInitialSourceData,
|
||||
calcFilesTreeLayoutNodes
|
||||
};
|
||||
|
||||
export default connect(null, mapDispatchToProps)(DataBusContainer);
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(DataBusContainer);
|
||||
|
|
|
|||
|
|
@ -2,50 +2,50 @@ import { ACTIONS } from './constants';
|
|||
import { getTreeLayout } from '../../../utils/treeLayout';
|
||||
|
||||
export const setInitialSourceData = data => ({
|
||||
type: ACTIONS.SET_INITIAL_SOURCE_DATA,
|
||||
payload: data
|
||||
type: ACTIONS.SET_INITIAL_SOURCE_DATA,
|
||||
payload: data
|
||||
});
|
||||
|
||||
export const calcFilesTreeLayoutNodes = () => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const { filesTree, closedFolders } = state.dataBus;
|
||||
const { checkedState } = state.viewSwitches;
|
||||
const state = getState();
|
||||
const { filesTree, closedFolders } = state.dataBus;
|
||||
const { checkedState } = state.viewSwitches;
|
||||
|
||||
if (!filesTree) return;
|
||||
if (!filesTree) return;
|
||||
|
||||
return dispatch({
|
||||
type: ACTIONS.UPDATE_FILES_TREE_LAYOUT_NODES,
|
||||
payload: getTreeLayout(filesTree, {
|
||||
includeFileChildren: checkedState.codeCrumbs,
|
||||
closedFolders
|
||||
})
|
||||
});
|
||||
return dispatch({
|
||||
type: ACTIONS.UPDATE_FILES_TREE_LAYOUT_NODES,
|
||||
payload: getTreeLayout(filesTree, {
|
||||
includeFileChildren: checkedState.codeCrumbs,
|
||||
closedFolders
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
export const selectFile = fileNode => ({
|
||||
type: ACTIONS.SELECT_FILE,
|
||||
payload: fileNode
|
||||
type: ACTIONS.SELECT_FILE,
|
||||
payload: fileNode
|
||||
});
|
||||
|
||||
export const toggleFolder = folderNode => ({
|
||||
type: ACTIONS.TOGGLE_FOLDER,
|
||||
payload: folderNode
|
||||
type: ACTIONS.TOGGLE_FOLDER,
|
||||
payload: folderNode
|
||||
});
|
||||
|
||||
export const openAllFolders = () => ({
|
||||
type: ACTIONS.OPEN_ALL_FOLDERS
|
||||
type: ACTIONS.OPEN_ALL_FOLDERS
|
||||
});
|
||||
|
||||
export const closeAllFolders = () => ({
|
||||
type: ACTIONS.CLOSE_ALL_FOLDERS
|
||||
type: ACTIONS.CLOSE_ALL_FOLDERS
|
||||
});
|
||||
|
||||
export const selectCodeCrumb = (fileNode, codeCrumb) => ({
|
||||
type: ACTIONS.SELECT_CODE_CRUMB,
|
||||
payload: { fileNode, codeCrumb }
|
||||
type: ACTIONS.SELECT_CODE_CRUMB,
|
||||
payload: { fileNode, codeCrumb }
|
||||
});
|
||||
|
||||
export const setDependenciesEntryPoint = (fileNode) => ({
|
||||
type: ACTIONS.SET_DEPENDENCIES_ENTRY_POINT,
|
||||
payload: fileNode
|
||||
export const setDependenciesEntryPoint = fileNode => ({
|
||||
type: ACTIONS.SET_DEPENDENCIES_ENTRY_POINT,
|
||||
payload: fileNode
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
export const ACTIONS = {
|
||||
SET_INITIAL_SOURCE_DATA: 'DATA_BUS.SET_INITIAL_SOURCE_DATA',
|
||||
UPDATE_FILES_TREE_LAYOUT_NODES: 'DATA_BUS.UPDATE_FILES_TREE_LAYOUT_NODES',
|
||||
SELECT_FILE: 'DATA_BUS.SELECT_FILE',
|
||||
TOGGLE_FOLDER: 'DATA_BUS.TOGGLE_FOLDER',
|
||||
OPEN_ALL_FOLDERS: 'DATA_BUS.OPEN_ALL_FOLDERS',
|
||||
CLOSE_ALL_FOLDERS: 'DATA_BUS.CLOSE_ALL_FOLDERS',
|
||||
SELECT_CODE_CRUMB: 'DATA_BUS.SELECT_CODE_CRUMB',
|
||||
SET_DEPENDENCIES_ENTRY_POINT: 'DATA_BUS.SET_DEPENDENCIES_ENTRY_POINT'
|
||||
SET_INITIAL_SOURCE_DATA: 'DATA_BUS.SET_INITIAL_SOURCE_DATA',
|
||||
UPDATE_FILES_TREE_LAYOUT_NODES: 'DATA_BUS.UPDATE_FILES_TREE_LAYOUT_NODES',
|
||||
SELECT_FILE: 'DATA_BUS.SELECT_FILE',
|
||||
TOGGLE_FOLDER: 'DATA_BUS.TOGGLE_FOLDER',
|
||||
OPEN_ALL_FOLDERS: 'DATA_BUS.OPEN_ALL_FOLDERS',
|
||||
CLOSE_ALL_FOLDERS: 'DATA_BUS.CLOSE_ALL_FOLDERS',
|
||||
SELECT_CODE_CRUMB: 'DATA_BUS.SELECT_CODE_CRUMB',
|
||||
SET_DEPENDENCIES_ENTRY_POINT: 'DATA_BUS.SET_DEPENDENCIES_ENTRY_POINT'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,96 +3,90 @@ import { DIR_NODE_TYPE } from '../../../../../shared/constants';
|
|||
import { ACTIONS } from './constants';
|
||||
|
||||
const DefaultState = {
|
||||
filesTree: null,
|
||||
filesList: null,
|
||||
dependenciesList: null,
|
||||
filesTree: null,
|
||||
filesList: null,
|
||||
dependenciesList: null,
|
||||
|
||||
filesTreeLayoutNodes: null,
|
||||
closedFolders: {},
|
||||
firstLevelFolders: {}
|
||||
filesTreeLayoutNodes: null,
|
||||
closedFolders: {},
|
||||
firstLevelFolders: {}
|
||||
};
|
||||
|
||||
export default (state = DefaultState, action) => {
|
||||
switch (action.type) {
|
||||
case ACTIONS.SET_INITIAL_SOURCE_DATA:
|
||||
return {
|
||||
...state,
|
||||
...action.payload,
|
||||
dependenciesRootEntryPoint: action.payload.dependenciesList[0],
|
||||
isCurrentDependenciesEntryPointRoot: true,
|
||||
switch (action.type) {
|
||||
case ACTIONS.SET_INITIAL_SOURCE_DATA:
|
||||
return {
|
||||
...state,
|
||||
...action.payload,
|
||||
dependenciesRootEntryPoint: action.payload.dependenciesList[0],
|
||||
isCurrentDependenciesEntryPointRoot: true,
|
||||
|
||||
firstLevelFolders: safeGet(
|
||||
action.payload,
|
||||
'filesTree.children',
|
||||
[]
|
||||
)
|
||||
.filter(item => item.type === DIR_NODE_TYPE)
|
||||
.reduce((res, item) => {
|
||||
res[item.path] = item;
|
||||
return res;
|
||||
}, {})
|
||||
};
|
||||
firstLevelFolders: safeGet(action.payload, 'filesTree.children', [])
|
||||
.filter(item => item.type === DIR_NODE_TYPE)
|
||||
.reduce((res, item) => {
|
||||
res[item.path] = item;
|
||||
return res;
|
||||
}, {})
|
||||
};
|
||||
|
||||
case ACTIONS.UPDATE_FILES_TREE_LAYOUT_NODES:
|
||||
return {
|
||||
...state,
|
||||
filesTreeLayoutNodes: action.payload
|
||||
};
|
||||
case ACTIONS.UPDATE_FILES_TREE_LAYOUT_NODES:
|
||||
return {
|
||||
...state,
|
||||
filesTreeLayoutNodes: action.payload
|
||||
};
|
||||
|
||||
case ACTIONS.SELECT_FILE:
|
||||
return {
|
||||
...state,
|
||||
selectedCodeCrumb: null,
|
||||
selectedFile: action.payload
|
||||
};
|
||||
case ACTIONS.SELECT_FILE:
|
||||
return {
|
||||
...state,
|
||||
selectedCodeCrumb: null,
|
||||
selectedFile: action.payload
|
||||
};
|
||||
|
||||
case ACTIONS.TOGGLE_FOLDER:
|
||||
const { closedFolders } = state;
|
||||
const folderPath = action.payload.path;
|
||||
case ACTIONS.TOGGLE_FOLDER:
|
||||
const { closedFolders } = state;
|
||||
const folderPath = action.payload.path;
|
||||
|
||||
return {
|
||||
...state,
|
||||
closedFolders: closedFolders[folderPath]
|
||||
? { ...closedFolders, [folderPath]: null }
|
||||
: { ...closedFolders, [folderPath]: action.payload }
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
closedFolders: closedFolders[folderPath]
|
||||
? { ...closedFolders, [folderPath]: null }
|
||||
: { ...closedFolders, [folderPath]: action.payload }
|
||||
};
|
||||
|
||||
case ACTIONS.OPEN_ALL_FOLDERS:
|
||||
return {
|
||||
...state,
|
||||
closedFolders: {}
|
||||
};
|
||||
case ACTIONS.OPEN_ALL_FOLDERS:
|
||||
return {
|
||||
...state,
|
||||
closedFolders: {}
|
||||
};
|
||||
|
||||
case ACTIONS.CLOSE_ALL_FOLDERS:
|
||||
return {
|
||||
...state,
|
||||
closedFolders: {
|
||||
...state.closedFolders,
|
||||
...state.firstLevelFolders
|
||||
}
|
||||
};
|
||||
case ACTIONS.CLOSE_ALL_FOLDERS:
|
||||
return {
|
||||
...state,
|
||||
closedFolders: {
|
||||
...state.closedFolders,
|
||||
...state.firstLevelFolders
|
||||
}
|
||||
};
|
||||
|
||||
case ACTIONS.SELECT_CODE_CRUMB:
|
||||
const { fileNode, codeCrumb } = action.payload;
|
||||
return {
|
||||
...state,
|
||||
selectedFile: fileNode,
|
||||
selectedCodeCrumb: codeCrumb
|
||||
};
|
||||
case ACTIONS.SELECT_CODE_CRUMB:
|
||||
const { fileNode, codeCrumb } = action.payload;
|
||||
return {
|
||||
...state,
|
||||
selectedFile: fileNode,
|
||||
selectedCodeCrumb: codeCrumb
|
||||
};
|
||||
|
||||
case ACTIONS.SET_DEPENDENCIES_ENTRY_POINT:
|
||||
const entry = action.payload;
|
||||
const rootEntryPointModuleName =
|
||||
state.dependenciesRootEntryPoint.moduleName;
|
||||
case ACTIONS.SET_DEPENDENCIES_ENTRY_POINT:
|
||||
const entry = action.payload;
|
||||
const rootEntryPointModuleName = state.dependenciesRootEntryPoint.moduleName;
|
||||
|
||||
return {
|
||||
...state,
|
||||
dependenciesEntryPoint: entry,
|
||||
isCurrentDependenciesEntryPointRoot:
|
||||
entry && entry.path === rootEntryPointModuleName
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
dependenciesEntryPoint: entry,
|
||||
isCurrentDependenciesEntryPointRoot: entry && entry.path === rootEntryPointModuleName
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@ import React from 'react';
|
|||
import debounce from 'lodash.debounce';
|
||||
|
||||
class ResizeWrapper extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handler = debounce(() => props.onResize());
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handler = debounce(() => props.onResize());
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.handler);
|
||||
}
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.handler);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.addEventListener('resize', this.handler);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
window.addEventListener('resize', this.handler);
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default ResizeWrapper;
|
||||
|
|
|
|||
|
|
@ -4,29 +4,26 @@ import SideBar from './component/SideBar';
|
|||
import { selectFile } from '../data-bus/store/actions';
|
||||
|
||||
const SideBarContainer = ({ selectedFile, selectedCodeCrumb, onClose }) => {
|
||||
if (!selectedFile) return null;
|
||||
if (!selectedFile) return null;
|
||||
|
||||
//TODO: add animation slide
|
||||
return (
|
||||
<SideBar
|
||||
file={selectedFile}
|
||||
codeCrumb={selectedCodeCrumb}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
//TODO: add animation slide
|
||||
return <SideBar file={selectedFile} codeCrumb={selectedCodeCrumb} onClose={onClose} />;
|
||||
};
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { selectedFile, selectedCodeCrumb } = state.dataBus;
|
||||
const { selectedFile, selectedCodeCrumb } = state.dataBus;
|
||||
|
||||
return {
|
||||
selectedFile,
|
||||
selectedCodeCrumb
|
||||
};
|
||||
return {
|
||||
selectedFile,
|
||||
selectedCodeCrumb
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onClose: () => dispatch(selectFile(null))
|
||||
onClose: () => dispatch(selectFile(null))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SideBarContainer);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(SideBarContainer);
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import { atomOneLight } from 'react-syntax-highlighter/styles/hljs';
|
|||
//TODO: scrool to/highlight crumbed lines
|
||||
//https://github.com/conorhastings/react-syntax-highlighter/blob/master/README.md
|
||||
export default ({ code, crumbedLines = [] }) => (
|
||||
<SyntaxHighlighter
|
||||
language="javascript"
|
||||
style={atomOneLight}
|
||||
customStyle={{ fontSize: '13px' }}
|
||||
showLineNumbers={true}
|
||||
>
|
||||
{code}
|
||||
</SyntaxHighlighter>
|
||||
<SyntaxHighlighter
|
||||
language="javascript"
|
||||
style={atomOneLight}
|
||||
customStyle={{ fontSize: '13px' }}
|
||||
showLineNumbers={true}
|
||||
>
|
||||
{code}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,37 +6,32 @@ import Code from './Code/Code';
|
|||
|
||||
//TODO: Add slide from right animation
|
||||
export default ({ file, codeCrumb, onClose }) => {
|
||||
const crumbedLines = !codeCrumb
|
||||
? []
|
||||
: codeCrumb.crumbedLineNode.loc.start.line;
|
||||
const crumbedLines = !codeCrumb ? [] : codeCrumb.crumbedLineNode.loc.start.line;
|
||||
|
||||
return (
|
||||
<div className="SideBar-container">
|
||||
<div className="SideBar-header">
|
||||
<div>{file.path}</div>
|
||||
<a href="#" onClick={onClose}>
|
||||
X
|
||||
</a>
|
||||
</div>
|
||||
return (
|
||||
<div className="SideBar-container">
|
||||
<div className="SideBar-header">
|
||||
<div>{file.path}</div>
|
||||
<a href="#" onClick={onClose}>
|
||||
X
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="SideBar-body">
|
||||
{file.fileCode && (
|
||||
<Tabs defaultActiveKey="1" onChange={() => {}}>
|
||||
<TabPane tab="Code" key="1">
|
||||
<Code
|
||||
code={file.fileCode}
|
||||
crumbedLines={crumbedLines}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane tab="FlowChart" key="2">
|
||||
Content of Tab Pane 2
|
||||
</TabPane>
|
||||
<TabPane tab="Crumbs" key="3">
|
||||
Content of Tab Pane 3
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div className="SideBar-body">
|
||||
{file.fileCode && (
|
||||
<Tabs defaultActiveKey="1" onChange={() => {}}>
|
||||
<TabPane tab="Code" key="1">
|
||||
<Code code={file.fileCode} crumbedLines={crumbedLines} />
|
||||
</TabPane>
|
||||
<TabPane tab="FlowChart" key="2">
|
||||
Content of Tab Pane 2
|
||||
</TabPane>
|
||||
<TabPane tab="Crumbs" key="3">
|
||||
Content of Tab Pane 3
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,40 +1,43 @@
|
|||
import { connect } from 'react-redux';
|
||||
import TreeDiagram from './component/TreeDiagram';
|
||||
import {
|
||||
selectCodeCrumb,
|
||||
selectFile,
|
||||
setDependenciesEntryPoint,
|
||||
toggleFolder
|
||||
selectCodeCrumb,
|
||||
selectFile,
|
||||
setDependenciesEntryPoint,
|
||||
toggleFolder
|
||||
} from '../data-bus/store/actions';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { checkedState } = state.viewSwitches;
|
||||
const {
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint
|
||||
} = state.dataBus;
|
||||
const { checkedState } = state.viewSwitches;
|
||||
const {
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint
|
||||
} = state.dataBus;
|
||||
|
||||
return {
|
||||
sourceDiagramOn: checkedState.source,
|
||||
dependenciesDiagramOn: checkedState.dependencies,
|
||||
dependenciesShowOneModule: checkedState.dependenciesShowOneModule,
|
||||
codeCrumbsDiagramOn: checkedState.codeCrumbs,
|
||||
codeCrumbsMinimize: checkedState.codeCrumbsMinimize,
|
||||
codeCrumbsDetails: checkedState.codeCrumbsDetails,
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint
|
||||
};
|
||||
return {
|
||||
sourceDiagramOn: checkedState.source,
|
||||
dependenciesDiagramOn: checkedState.dependencies,
|
||||
dependenciesShowOneModule: checkedState.dependenciesShowOneModule,
|
||||
codeCrumbsDiagramOn: checkedState.codeCrumbs,
|
||||
codeCrumbsMinimize: checkedState.codeCrumbsMinimize,
|
||||
codeCrumbsDetails: checkedState.codeCrumbsDetails,
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
onCodeCrumbSelect: selectCodeCrumb,
|
||||
onFileSelect: selectFile,
|
||||
onFileIconClick: setDependenciesEntryPoint,
|
||||
onFolderClick: toggleFolder
|
||||
onCodeCrumbSelect: selectCodeCrumb,
|
||||
onFileSelect: selectFile,
|
||||
onFileIconClick: setDependenciesEntryPoint,
|
||||
onFolderClick: toggleFolder
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TreeDiagram);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TreeDiagram);
|
||||
|
|
|
|||
|
|
@ -1,165 +1,148 @@
|
|||
import React from 'react';
|
||||
import { withSvgDraw } from '../utils/SvgDraw';
|
||||
import {
|
||||
drawCodeCrumbEdge,
|
||||
drawPartEdge,
|
||||
drawCodeCrumbLoc,
|
||||
drawPopOver
|
||||
} from './drawHelpers';
|
||||
import { drawCodeCrumbEdge, drawPartEdge, drawCodeCrumbLoc, drawPopOver } from './drawHelpers';
|
||||
import { drawFileText, drawFileIcon } from '../SourceTree/drawHelpers';
|
||||
|
||||
import { getFilesList } from '../../../../utils/treeLayout';
|
||||
import { createSet } from '../utils/SvgSet';
|
||||
|
||||
class CodeCrumbsTree extends React.Component {
|
||||
componentDidMount() {
|
||||
this.drawSet = createSet(this.props.primaryDraw);
|
||||
this.drawTree();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.drawSet = createSet(this.props.primaryDraw);
|
||||
this.drawTree();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.clearDraw();
|
||||
this.drawTree();
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.clearDraw();
|
||||
this.drawTree();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clearDraw();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.clearDraw();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return true;
|
||||
//TODO: missing overlapping elements: text&icons
|
||||
/*const oldProps = this.props;
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return true;
|
||||
//TODO: missing overlapping elements: text&icons
|
||||
/*const oldProps = this.props;
|
||||
return oldProps.filesTreeLayoutNodes !== nextProps.filesTreeLayoutNodes;*/
|
||||
}
|
||||
}
|
||||
|
||||
clearDraw() {
|
||||
this.drawSet.clearAll();
|
||||
}
|
||||
clearDraw() {
|
||||
this.drawSet.clearAll();
|
||||
}
|
||||
|
||||
drawTree() {
|
||||
const {
|
||||
primaryDraw,
|
||||
filesTreeLayoutNodes,
|
||||
shiftToCenterPoint,
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails,
|
||||
onCodeCrumbSelect
|
||||
} = this.props;
|
||||
drawTree() {
|
||||
const {
|
||||
primaryDraw,
|
||||
filesTreeLayoutNodes,
|
||||
shiftToCenterPoint,
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails,
|
||||
onCodeCrumbSelect
|
||||
} = this.props;
|
||||
|
||||
const { add } = this.drawSet;
|
||||
const { add } = this.drawSet;
|
||||
|
||||
const filesList = getFilesList(filesTreeLayoutNodes);
|
||||
filesList.forEach(node => {
|
||||
const [nX, nY] = [node.y, node.x];
|
||||
const filesList = getFilesList(filesTreeLayoutNodes);
|
||||
filesList.forEach(node => {
|
||||
const [nX, nY] = [node.y, node.x];
|
||||
|
||||
if (node.children) {
|
||||
if (!sourceDiagramOn && !dependenciesDiagramOn) {
|
||||
add(
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
name: node.data.name
|
||||
})
|
||||
);
|
||||
if (node.children) {
|
||||
if (!sourceDiagramOn && !dependenciesDiagramOn) {
|
||||
add(
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
name: node.data.name
|
||||
})
|
||||
);
|
||||
|
||||
add(
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
codeCrumbsMinimize
|
||||
})
|
||||
);
|
||||
add(
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
codeCrumbsMinimize
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
!codeCrumbsMinimize &&
|
||||
add(
|
||||
drawPartEdge(primaryDraw, shiftToCenterPoint, {
|
||||
source: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
parentName: node.data.name
|
||||
})
|
||||
);
|
||||
|
||||
!codeCrumbsMinimize &&
|
||||
node.children.forEach((crumb, i, list) => {
|
||||
const [cX, cY] = [crumb.y, crumb.x];
|
||||
const singleCrumb = list.length === 1;
|
||||
|
||||
!singleCrumb &&
|
||||
add(
|
||||
drawCodeCrumbEdge(primaryDraw, shiftToCenterPoint, {
|
||||
source: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
target: {
|
||||
x: cX,
|
||||
y: cY
|
||||
},
|
||||
parentName: node.data.name
|
||||
})
|
||||
);
|
||||
|
||||
//TODO: refactor mess
|
||||
const loc = crumb.data.crumbedLineNode.loc.start;
|
||||
add(
|
||||
drawCodeCrumbLoc(primaryDraw, shiftToCenterPoint, {
|
||||
x: cX,
|
||||
y: cY,
|
||||
loc: `(${loc.line},${loc.column})`,
|
||||
name: crumb.data.name,
|
||||
singleCrumb,
|
||||
onMouseOver() {
|
||||
if (!crumb.data.params.details || codeCrumbsDetails) return null;
|
||||
|
||||
return drawPopOver(primaryDraw, shiftToCenterPoint, {
|
||||
x: cX,
|
||||
y: cY,
|
||||
name: crumb.data.params.details,
|
||||
singleCrumb
|
||||
});
|
||||
},
|
||||
onClick() {
|
||||
onCodeCrumbSelect(node.data, crumb.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
!codeCrumbsMinimize &&
|
||||
add(
|
||||
drawPartEdge(primaryDraw, shiftToCenterPoint, {
|
||||
source: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
parentName: node.data.name
|
||||
})
|
||||
);
|
||||
|
||||
!codeCrumbsMinimize &&
|
||||
node.children.forEach((crumb, i, list) => {
|
||||
const [cX, cY] = [crumb.y, crumb.x];
|
||||
const singleCrumb = list.length === 1;
|
||||
|
||||
!singleCrumb &&
|
||||
add(
|
||||
drawCodeCrumbEdge(
|
||||
primaryDraw,
|
||||
shiftToCenterPoint,
|
||||
{
|
||||
source: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
target: {
|
||||
x: cX,
|
||||
y: cY
|
||||
},
|
||||
parentName: node.data.name
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
//TODO: refactor mess
|
||||
const loc = crumb.data.crumbedLineNode.loc.start;
|
||||
add(
|
||||
drawCodeCrumbLoc(primaryDraw, shiftToCenterPoint, {
|
||||
x: cX,
|
||||
y: cY,
|
||||
loc: `(${loc.line},${loc.column})`,
|
||||
name: crumb.data.name,
|
||||
singleCrumb,
|
||||
onMouseOver() {
|
||||
if (
|
||||
!crumb.data.params.details ||
|
||||
codeCrumbsDetails
|
||||
)
|
||||
return null;
|
||||
|
||||
return drawPopOver(
|
||||
primaryDraw,
|
||||
shiftToCenterPoint,
|
||||
{
|
||||
x: cX,
|
||||
y: cY,
|
||||
name: crumb.data.params.details,
|
||||
singleCrumb
|
||||
}
|
||||
);
|
||||
},
|
||||
onClick() {
|
||||
onCodeCrumbSelect(node.data, crumb.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (codeCrumbsDetails && crumb.data.params.details) {
|
||||
add(
|
||||
drawPopOver(primaryDraw, shiftToCenterPoint, {
|
||||
x: cX,
|
||||
y: cY,
|
||||
name: crumb.data.params.details,
|
||||
singleCrumb
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
if (codeCrumbsDetails && crumb.data.params.details) {
|
||||
add(
|
||||
drawPopOver(primaryDraw, shiftToCenterPoint, {
|
||||
x: cX,
|
||||
y: cY,
|
||||
name: crumb.data.params.details,
|
||||
singleCrumb
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default withSvgDraw(CodeCrumbsTree);
|
||||
|
|
|
|||
|
|
@ -1,135 +1,113 @@
|
|||
import { PURPLE_COLOR, BLUE_COLOR, SYMBOL_WIDTH } from '../../store/constants';
|
||||
|
||||
export const drawCodeCrumbEdge = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ target, source, parentName }
|
||||
) => {
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 40;
|
||||
const edgeTurnDistance = 20;
|
||||
export const drawCodeCrumbEdge = (draw, shiftToCenterPoint, { target, source, parentName }) => {
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 40;
|
||||
const edgeTurnDistance = 20;
|
||||
|
||||
const P1 = shiftToCenterPoint(source.x + nameWidth + padding, source.y);
|
||||
const P1 = shiftToCenterPoint(source.x + nameWidth + padding, source.y);
|
||||
|
||||
const P2 = shiftToCenterPoint(target.x - edgeTurnDistance, source.y);
|
||||
const P3 = shiftToCenterPoint(target.x - edgeTurnDistance, target.y);
|
||||
const P4 = shiftToCenterPoint(target.x, target.y);
|
||||
const P2 = shiftToCenterPoint(target.x - edgeTurnDistance, source.y);
|
||||
const P3 = shiftToCenterPoint(target.x - edgeTurnDistance, target.y);
|
||||
const P4 = shiftToCenterPoint(target.x, target.y);
|
||||
|
||||
const polyline = draw.polyline([
|
||||
[P1.x, P1.y],
|
||||
[P2.x, P2.y],
|
||||
[P3.x, P3.y],
|
||||
[P4.x, P4.y]
|
||||
]);
|
||||
const polyline = draw.polyline([[P1.x, P1.y], [P2.x, P2.y], [P3.x, P3.y], [P4.x, P4.y]]);
|
||||
|
||||
polyline.fill('none').stroke({
|
||||
color: PURPLE_COLOR
|
||||
});
|
||||
polyline.fill('none').stroke({
|
||||
color: PURPLE_COLOR
|
||||
});
|
||||
|
||||
return polyline;
|
||||
return polyline;
|
||||
};
|
||||
|
||||
export const drawPartEdge = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ source, parentName }
|
||||
) => {
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 17;
|
||||
export const drawPartEdge = (draw, shiftToCenterPoint, { source, parentName }) => {
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 17;
|
||||
|
||||
const P1 = shiftToCenterPoint(source.x + nameWidth + padding, source.y);
|
||||
const P2 = { x: P1.x + padding + 6, y: P1.y };
|
||||
const P1 = shiftToCenterPoint(source.x + nameWidth + padding, source.y);
|
||||
const P2 = { x: P1.x + padding + 6, y: P1.y };
|
||||
|
||||
const polyline = draw.polyline([[P1.x, P1.y], [P2.x, P2.y]]);
|
||||
const polyline = draw.polyline([[P1.x, P1.y], [P2.x, P2.y]]);
|
||||
|
||||
polyline.fill('none').stroke({
|
||||
color: PURPLE_COLOR
|
||||
});
|
||||
polyline.fill('none').stroke({
|
||||
color: PURPLE_COLOR
|
||||
});
|
||||
|
||||
const smallLine = draw
|
||||
.line(P1.x, P1.y - 2, P1.x, P1.y + 2)
|
||||
.stroke({ color: PURPLE_COLOR });
|
||||
const smallLine = draw.line(P1.x, P1.y - 2, P1.x, P1.y + 2).stroke({ color: PURPLE_COLOR });
|
||||
|
||||
return [polyline, smallLine];
|
||||
return [polyline, smallLine];
|
||||
};
|
||||
|
||||
export const drawCodeCrumbLoc = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, name = '', loc, singleCrumb, onClick, onMouseOver }
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, name = '', loc, singleCrumb, onClick, onMouseOver }
|
||||
) => {
|
||||
const textPointShiftX = 3;
|
||||
const textPointShiftY = 5;
|
||||
const textPoint = shiftToCenterPoint(singleCrumb ? x - 20 : x, y);
|
||||
const textPointShiftX = 3;
|
||||
const textPointShiftY = 5;
|
||||
const textPoint = shiftToCenterPoint(singleCrumb ? x - 20 : x, y);
|
||||
|
||||
const locWidth = loc.length * 6;
|
||||
const locRec = draw
|
||||
.rect(locWidth, 12)
|
||||
.fill('#fff')
|
||||
.stroke(PURPLE_COLOR)
|
||||
.move(textPoint.x, textPoint.y - 6);
|
||||
const locWidth = loc.length * 6;
|
||||
const locRec = draw
|
||||
.rect(locWidth, 12)
|
||||
.fill('#fff')
|
||||
.stroke(PURPLE_COLOR)
|
||||
.move(textPoint.x, textPoint.y - 6);
|
||||
|
||||
const locText = draw.text(loc);
|
||||
locText
|
||||
.font({ fill: '#595959', family: 'Menlo', size: '8px' })
|
||||
.style({ cursor: 'pointer' })
|
||||
.move(textPoint.x + textPointShiftX, textPoint.y - textPointShiftY);
|
||||
const locText = draw.text(loc);
|
||||
locText
|
||||
.font({ fill: '#595959', family: 'Menlo', size: '8px' })
|
||||
.style({ cursor: 'pointer' })
|
||||
.move(textPoint.x + textPointShiftX, textPoint.y - textPointShiftY);
|
||||
|
||||
if (onMouseOver) {
|
||||
let popOver = null;
|
||||
locText.on('mouseover', () => {
|
||||
popOver = onMouseOver();
|
||||
});
|
||||
locText.on('mouseout', () => {
|
||||
popOver && popOver[0].remove() && popOver[1].remove();
|
||||
});
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
locText.on('click', onClick);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
const nameText = draw.text(':' + name);
|
||||
nameText.font({ fill: '#595959', family: 'Menlo', size: '12px' });
|
||||
//TODO: refactor to use one way, plus or minus
|
||||
nameText.move(
|
||||
textPoint.x + textPointShiftX + locWidth - 1,
|
||||
textPoint.y - textPointShiftY - 2
|
||||
);
|
||||
|
||||
return [locRec, locText, nameText];
|
||||
}
|
||||
|
||||
return [locRec, locText];
|
||||
};
|
||||
|
||||
export const drawPopOver = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, name = '', singleCrumb }
|
||||
) => {
|
||||
const tPt = shiftToCenterPoint(x - 15 + (singleCrumb ? 0 : 20), y - 24);
|
||||
const nameWidth = name.length * 6;
|
||||
const nameHeight = 8;
|
||||
const padding = 5;
|
||||
|
||||
const polyline = draw.polyline([
|
||||
[tPt.x - padding, tPt.y + nameHeight + padding + 3],
|
||||
[tPt.x - padding, tPt.y - padding],
|
||||
[tPt.x + nameWidth + 2 * padding, tPt.y - padding],
|
||||
[tPt.x + nameWidth + 2 * padding, tPt.y + nameHeight + padding],
|
||||
[tPt.x - padding + 3, tPt.y + nameHeight + padding],
|
||||
[tPt.x - padding, tPt.y + nameHeight + padding + 3]
|
||||
]);
|
||||
|
||||
polyline.fill('#fff').stroke({
|
||||
color: PURPLE_COLOR
|
||||
if (onMouseOver) {
|
||||
let popOver = null;
|
||||
locText.on('mouseover', () => {
|
||||
popOver = onMouseOver();
|
||||
});
|
||||
locText.on('mouseout', () => {
|
||||
popOver && popOver[0].remove() && popOver[1].remove();
|
||||
});
|
||||
}
|
||||
|
||||
const text = draw.text(name);
|
||||
text.font({ fill: '#595959', family: 'Menlo', size: '10px' });
|
||||
text.move(tPt.x+2, tPt.y - 1);
|
||||
if (onClick) {
|
||||
locText.on('click', onClick);
|
||||
}
|
||||
|
||||
return [text, polyline];
|
||||
if (name) {
|
||||
const nameText = draw.text(':' + name);
|
||||
nameText.font({ fill: '#595959', family: 'Menlo', size: '12px' });
|
||||
//TODO: refactor to use one way, plus or minus
|
||||
nameText.move(textPoint.x + textPointShiftX + locWidth - 1, textPoint.y - textPointShiftY - 2);
|
||||
|
||||
return [locRec, locText, nameText];
|
||||
}
|
||||
|
||||
return [locRec, locText];
|
||||
};
|
||||
|
||||
export const drawPopOver = (draw, shiftToCenterPoint, { x, y, name = '', singleCrumb }) => {
|
||||
const tPt = shiftToCenterPoint(x - 15 + (singleCrumb ? 0 : 20), y - 24);
|
||||
const nameWidth = name.length * 6;
|
||||
const nameHeight = 8;
|
||||
const padding = 5;
|
||||
|
||||
const polyline = draw.polyline([
|
||||
[tPt.x - padding, tPt.y + nameHeight + padding + 3],
|
||||
[tPt.x - padding, tPt.y - padding],
|
||||
[tPt.x + nameWidth + 2 * padding, tPt.y - padding],
|
||||
[tPt.x + nameWidth + 2 * padding, tPt.y + nameHeight + padding],
|
||||
[tPt.x - padding + 3, tPt.y + nameHeight + padding],
|
||||
[tPt.x - padding, tPt.y + nameHeight + padding + 3]
|
||||
]);
|
||||
|
||||
polyline.fill('#fff').stroke({
|
||||
color: PURPLE_COLOR
|
||||
});
|
||||
|
||||
const text = draw.text(name);
|
||||
text.font({ fill: '#595959', family: 'Menlo', size: '10px' });
|
||||
text.move(tPt.x + 2, tPt.y - 1);
|
||||
|
||||
return [text, polyline];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,125 +5,104 @@ import { getFilesList } from '../../../../utils/treeLayout';
|
|||
import { withSvgDraw } from '../utils/SvgDraw';
|
||||
|
||||
class DependenciesTree extends React.Component {
|
||||
componentDidMount() {
|
||||
this.drawTree();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.drawTree();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { primaryDraw } = this.props;
|
||||
componentDidUpdate() {
|
||||
const { primaryDraw } = this.props;
|
||||
|
||||
primaryDraw.clear();
|
||||
this.drawTree();
|
||||
}
|
||||
//move to utils
|
||||
findNodeByPathName = (list = [], pathName) => {
|
||||
return list.find(l => l.data.path === pathName);
|
||||
primaryDraw.clear();
|
||||
this.drawTree();
|
||||
}
|
||||
//move to utils
|
||||
findNodeByPathName = (list = [], pathName) => {
|
||||
return list.find(l => l.data.path === pathName);
|
||||
};
|
||||
|
||||
getFilteredDependenciesList() {
|
||||
const { dependenciesList, dependenciesEntryPoint, dependenciesShowOneModule } = this.props;
|
||||
|
||||
const entryPoint = dependenciesEntryPoint || {
|
||||
path: dependenciesList[0].moduleName
|
||||
};
|
||||
|
||||
getFilteredDependenciesList() {
|
||||
const {
|
||||
dependenciesList,
|
||||
dependenciesEntryPoint,
|
||||
dependenciesShowOneModule
|
||||
} = this.props;
|
||||
|
||||
const entryPoint = dependenciesEntryPoint || {
|
||||
path: dependenciesList[0].moduleName
|
||||
};
|
||||
|
||||
if (dependenciesShowOneModule) {
|
||||
return [
|
||||
dependenciesList.find(d => d.moduleName === entryPoint.path)
|
||||
];
|
||||
}
|
||||
|
||||
return this.collectDependencies(entryPoint.path, dependenciesList);
|
||||
if (dependenciesShowOneModule) {
|
||||
return [dependenciesList.find(d => d.moduleName === entryPoint.path)];
|
||||
}
|
||||
|
||||
collectDependencies(entryModuleName, dependenciesList) {
|
||||
let queue = [].concat(entryModuleName),
|
||||
store = [];
|
||||
return this.collectDependencies(entryPoint.path, dependenciesList);
|
||||
}
|
||||
|
||||
while (queue.length) {
|
||||
let moduleName = queue.shift(),
|
||||
entryModule = dependenciesList.find(
|
||||
d => d.moduleName === moduleName
|
||||
);
|
||||
collectDependencies(entryModuleName, dependenciesList) {
|
||||
let queue = [].concat(entryModuleName),
|
||||
store = [];
|
||||
|
||||
store.push(entryModule);
|
||||
while (queue.length) {
|
||||
let moduleName = queue.shift(),
|
||||
entryModule = dependenciesList.find(d => d.moduleName === moduleName);
|
||||
|
||||
const nodeBody = entryModule.importedModuleNames;
|
||||
if (nodeBody) {
|
||||
queue = [...queue, ...nodeBody];
|
||||
}
|
||||
}
|
||||
store.push(entryModule);
|
||||
|
||||
return store;
|
||||
const nodeBody = entryModule.importedModuleNames;
|
||||
if (nodeBody) {
|
||||
queue = [...queue, ...nodeBody];
|
||||
}
|
||||
}
|
||||
|
||||
drawTree() {
|
||||
const {
|
||||
primaryDraw,
|
||||
filesTreeLayoutNodes,
|
||||
shiftToCenterPoint,
|
||||
sourceDiagramOn
|
||||
} = this.props;
|
||||
return store;
|
||||
}
|
||||
|
||||
const moduleFilesList = getFilesList(filesTreeLayoutNodes);
|
||||
const filteredDependenciesList = this.getFilteredDependenciesList();
|
||||
drawTree() {
|
||||
const { primaryDraw, filesTreeLayoutNodes, shiftToCenterPoint, sourceDiagramOn } = this.props;
|
||||
|
||||
filteredDependenciesList.forEach(
|
||||
({ moduleName, importedModuleNames }) => {
|
||||
const moduleNode = this.findNodeByPathName(
|
||||
moduleFilesList,
|
||||
moduleName
|
||||
);
|
||||
const moduleFilesList = getFilesList(filesTreeLayoutNodes);
|
||||
const filteredDependenciesList = this.getFilteredDependenciesList();
|
||||
|
||||
if (!moduleNode) return;
|
||||
filteredDependenciesList.forEach(({ moduleName, importedModuleNames }) => {
|
||||
const moduleNode = this.findNodeByPathName(moduleFilesList, moduleName);
|
||||
|
||||
const [mX, mY] = [moduleNode.y, moduleNode.x];
|
||||
if (!moduleNode) return;
|
||||
|
||||
if (!sourceDiagramOn) {
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: mX,
|
||||
y: mY,
|
||||
name: moduleNode.data.name
|
||||
});
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: mX,
|
||||
y: mY
|
||||
});
|
||||
}
|
||||
const [mX, mY] = [moduleNode.y, moduleNode.x];
|
||||
|
||||
importedModuleNames.reduce((prevSource, name) => {
|
||||
const importedNode = this.findNodeByPathName(
|
||||
moduleFilesList,
|
||||
name
|
||||
);
|
||||
if (!sourceDiagramOn) {
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: mX,
|
||||
y: mY,
|
||||
name: moduleNode.data.name
|
||||
});
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: mX,
|
||||
y: mY
|
||||
});
|
||||
}
|
||||
|
||||
if (!importedNode) return;
|
||||
importedModuleNames.reduce((prevSource, name) => {
|
||||
const importedNode = this.findNodeByPathName(moduleFilesList, name);
|
||||
|
||||
const [iX, iY] = [importedNode.y, importedNode.x];
|
||||
//TODO: implementation iterations:
|
||||
//1) done: first with sharp angles + overlay
|
||||
//2) done: without overlaying, not fot all cases
|
||||
//3) rounded angles
|
||||
const source = { x: iX, y: iY };
|
||||
drawDependenciesEdge(primaryDraw, shiftToCenterPoint, {
|
||||
source,
|
||||
target: { x: mX, y: mY },
|
||||
prevSource
|
||||
});
|
||||
if (!importedNode) return;
|
||||
|
||||
return source;
|
||||
}, null);
|
||||
}
|
||||
);
|
||||
}
|
||||
const [iX, iY] = [importedNode.y, importedNode.x];
|
||||
//TODO: implementation iterations:
|
||||
//1) done: first with sharp angles + overlay
|
||||
//2) done: without overlaying, not fot all cases
|
||||
//3) rounded angles
|
||||
const source = { x: iX, y: iY };
|
||||
drawDependenciesEdge(primaryDraw, shiftToCenterPoint, {
|
||||
source,
|
||||
target: { x: mX, y: mY },
|
||||
prevSource
|
||||
});
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
return source;
|
||||
}, null);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default withSvgDraw(DependenciesTree);
|
||||
|
|
|
|||
|
|
@ -4,95 +4,83 @@ import { BLUE_COLOR, PURPLE_COLOR } from '../../store/constants';
|
|||
|
||||
const COLOR = BLUE_COLOR;
|
||||
|
||||
export const drawDependenciesEdge = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ source, target, prevSource }
|
||||
) => {
|
||||
const padding = 30;
|
||||
const halfPadding = padding / 2 - 5;
|
||||
export const drawDependenciesEdge = (draw, shiftToCenterPoint, { source, target, prevSource }) => {
|
||||
const padding = 30;
|
||||
const halfPadding = padding / 2 - 5;
|
||||
|
||||
const sourcePt = shiftToCenterPoint(
|
||||
target.y > source.y ? source.x + 10 : source.x + 8,
|
||||
target.y > source.y ? source.y + 7 : source.y - 12
|
||||
);
|
||||
drawSourceDotLine(draw, sourcePt);
|
||||
const sourcePt = shiftToCenterPoint(
|
||||
target.y > source.y ? source.x + 10 : source.x + 8,
|
||||
target.y > source.y ? source.y + 7 : source.y - 12
|
||||
);
|
||||
drawSourceDotLine(draw, sourcePt);
|
||||
|
||||
if (!prevSource) {
|
||||
const targetPt = shiftToCenterPoint(target.x, target.y);
|
||||
if (!prevSource) {
|
||||
const targetPt = shiftToCenterPoint(target.x, target.y);
|
||||
|
||||
const P1 = { x: sourcePt.x, y: targetPt.y + padding - 6};
|
||||
const P2 = { x: targetPt.x - halfPadding, y: targetPt.y + padding -6 };
|
||||
const P3 = { x: targetPt.x - halfPadding, y: targetPt.y };
|
||||
const P1 = { x: sourcePt.x, y: targetPt.y + padding - 6 };
|
||||
const P2 = { x: targetPt.x - halfPadding, y: targetPt.y + padding - 6 };
|
||||
const P3 = { x: targetPt.x - halfPadding, y: targetPt.y };
|
||||
|
||||
drawConnectionLine(draw, [
|
||||
[sourcePt.x, sourcePt.y],
|
||||
[P1.x, P1.y],
|
||||
[P2.x, P2.y],
|
||||
[P3.x, P3.y],
|
||||
[targetPt.x, targetPt.y]
|
||||
]);
|
||||
drawConnectionLine(draw, [
|
||||
[sourcePt.x, sourcePt.y],
|
||||
[P1.x, P1.y],
|
||||
[P2.x, P2.y],
|
||||
[P3.x, P3.y],
|
||||
[targetPt.x, targetPt.y]
|
||||
]);
|
||||
|
||||
drawArrow(draw, shiftToCenterPoint, target.x, target.y + 6);
|
||||
} else {
|
||||
if (prevSource.x < sourcePt.x) { //TODO: handle other cases
|
||||
const prevSourcePt = shiftToCenterPoint(prevSource.x, prevSource.y);
|
||||
drawArrow(draw, shiftToCenterPoint, target.x, target.y + 6);
|
||||
} else {
|
||||
if (prevSource.x < sourcePt.x) {
|
||||
//TODO: handle other cases
|
||||
const prevSourcePt = shiftToCenterPoint(prevSource.x, prevSource.y);
|
||||
|
||||
const P1 = { x: sourcePt.x, y: sourcePt.y + halfPadding -3};
|
||||
const P2 = {
|
||||
x: prevSourcePt.x + halfPadding,
|
||||
y: sourcePt.y + halfPadding-3
|
||||
};
|
||||
const P1 = { x: sourcePt.x, y: sourcePt.y + halfPadding - 3 };
|
||||
const P2 = {
|
||||
x: prevSourcePt.x + halfPadding,
|
||||
y: sourcePt.y + halfPadding - 3
|
||||
};
|
||||
|
||||
drawConnectionLine(draw, [
|
||||
[sourcePt.x, sourcePt.y],
|
||||
[P1.x, P1.y],
|
||||
[P2.x, P2.y]
|
||||
]);
|
||||
drawConnectionLine(draw, [[sourcePt.x, sourcePt.y], [P1.x, P1.y], [P2.x, P2.y]]);
|
||||
|
||||
drawDot(draw, P2)
|
||||
}
|
||||
drawDot(draw, P2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const drawDot = (draw, { x, y }) => {
|
||||
const radius = 4;
|
||||
const halfRadius = radius / 2;
|
||||
const radius = 4;
|
||||
const halfRadius = radius / 2;
|
||||
|
||||
draw
|
||||
.circle(radius)
|
||||
.fill(BLUE_COLOR)
|
||||
.move(x - halfRadius, y - halfRadius);
|
||||
draw
|
||||
.circle(radius)
|
||||
.fill(BLUE_COLOR)
|
||||
.move(x - halfRadius, y - halfRadius);
|
||||
};
|
||||
|
||||
const drawConnectionLine = (draw, points) => {
|
||||
const polyline = draw.polyline(points);
|
||||
const polyline = draw.polyline(points);
|
||||
|
||||
polyline.fill('none').stroke({
|
||||
color: COLOR
|
||||
});
|
||||
polyline.fill('none').stroke({
|
||||
color: COLOR
|
||||
});
|
||||
};
|
||||
|
||||
const drawSourceDotLine = (draw, { x, y }) => {
|
||||
draw.line(x - 3, y, x + 3, y).stroke({ width: 1, color: COLOR });
|
||||
draw.line(x - 3, y, x + 3, y).stroke({ width: 1, color: COLOR });
|
||||
};
|
||||
|
||||
const drawArrow = (draw, shiftToCenterPoint, nX, nY) => {
|
||||
const fileIconPath = 'resources/right-arrow.svg';
|
||||
const fileIconSize = 7;
|
||||
const fileIconPointShiftX = -4;
|
||||
const fileIconPointShiftY = 9.5;
|
||||
const fileIconPoint = shiftToCenterPoint(
|
||||
nX + fileIconPointShiftX,
|
||||
nY - fileIconPointShiftY
|
||||
);
|
||||
const fileIconPath = 'resources/right-arrow.svg';
|
||||
const fileIconSize = 7;
|
||||
const fileIconPointShiftX = -4;
|
||||
const fileIconPointShiftY = 9.5;
|
||||
const fileIconPoint = shiftToCenterPoint(nX + fileIconPointShiftX, nY - fileIconPointShiftY);
|
||||
|
||||
draw
|
||||
.rect(5, 6)
|
||||
.fill('#fff')
|
||||
.move(fileIconPoint.x + 2, fileIconPoint.y);
|
||||
draw
|
||||
.rect(5, 6)
|
||||
.fill('#fff')
|
||||
.move(fileIconPoint.x + 2, fileIconPoint.y);
|
||||
|
||||
draw
|
||||
.image(fileIconPath, fileIconSize, fileIconSize)
|
||||
.move(fileIconPoint.x, fileIconPoint.y);
|
||||
draw.image(fileIconPath, fileIconSize, fileIconSize).move(fileIconPoint.x, fileIconPoint.y);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,147 +1,143 @@
|
|||
import React from 'react';
|
||||
import { withSvgDraw } from '../utils/SvgDraw';
|
||||
import {
|
||||
drawDot,
|
||||
drawSourceEdge,
|
||||
drawFileText,
|
||||
drawFileIcon,
|
||||
drawFolderText,
|
||||
drawFolderIcon
|
||||
drawDot,
|
||||
drawSourceEdge,
|
||||
drawFileText,
|
||||
drawFileIcon,
|
||||
drawFolderText,
|
||||
drawFolderIcon
|
||||
} from './drawHelpers';
|
||||
|
||||
import {
|
||||
FILE_NODE_TYPE,
|
||||
DIR_NODE_TYPE
|
||||
} from '../../../../../../shared/constants';
|
||||
import { FILE_NODE_TYPE, DIR_NODE_TYPE } from '../../../../../../shared/constants';
|
||||
import { createSet } from '../utils/SvgSet';
|
||||
|
||||
class SourceTree extends React.Component {
|
||||
componentDidMount() {
|
||||
this.drawSet = createSet(this.props.primaryDraw);
|
||||
this.drawTree();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.drawSet = createSet(this.props.primaryDraw);
|
||||
this.drawTree();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.clearPrimaryDraw();
|
||||
this.clearSecondaryDraw();
|
||||
componentDidUpdate() {
|
||||
this.clearPrimaryDraw();
|
||||
this.clearSecondaryDraw();
|
||||
this.drawTree();
|
||||
}
|
||||
|
||||
this.drawTree();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.clearPrimaryDraw();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clearPrimaryDraw();
|
||||
}
|
||||
clearPrimaryDraw() {
|
||||
this.drawSet.clearAll();
|
||||
}
|
||||
|
||||
clearPrimaryDraw() {
|
||||
this.drawSet.clearAll();
|
||||
}
|
||||
clearSecondaryDraw() {
|
||||
this.props.secondaryDraw.clear();
|
||||
}
|
||||
|
||||
clearSecondaryDraw() {
|
||||
this.props.secondaryDraw.clear();
|
||||
}
|
||||
drawTree() {
|
||||
const {
|
||||
primaryDraw,
|
||||
secondaryDraw,
|
||||
layoutNodes,
|
||||
closedFolders,
|
||||
shiftToCenterPoint,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
onFileSelect,
|
||||
onFileIconClick,
|
||||
onFolderClick
|
||||
} = this.props;
|
||||
|
||||
drawTree() {
|
||||
const {
|
||||
primaryDraw,
|
||||
secondaryDraw,
|
||||
layoutNodes,
|
||||
closedFolders,
|
||||
shiftToCenterPoint,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
onFileSelect,
|
||||
onFileIconClick,
|
||||
onFolderClick
|
||||
} = this.props;
|
||||
const { add } = this.drawSet;
|
||||
|
||||
const { add } = this.drawSet;
|
||||
//note: instance from d3-flex tree, not Array
|
||||
layoutNodes.each(node => {
|
||||
const [nX, nY] = [node.y, node.x];
|
||||
const parent = node.parent;
|
||||
|
||||
//note: instance from d3-flex tree, not Array
|
||||
layoutNodes.each(node => {
|
||||
const [nX, nY] = [node.y, node.x];
|
||||
const parent = node.parent;
|
||||
if (parent && parent.data.type === DIR_NODE_TYPE) {
|
||||
const [pX, pY] = [parent.y, parent.x];
|
||||
|
||||
if (parent && parent.data.type === DIR_NODE_TYPE) {
|
||||
const [pX, pY] = [parent.y, parent.x];
|
||||
|
||||
drawSourceEdge(secondaryDraw, shiftToCenterPoint, {
|
||||
disabled: dependenciesDiagramOn,
|
||||
target: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
source: {
|
||||
x: pX,
|
||||
y: pY
|
||||
},
|
||||
singleChild: parent.children.length === 1
|
||||
});
|
||||
}
|
||||
|
||||
if (node.data.type === FILE_NODE_TYPE) {
|
||||
drawDot(secondaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn
|
||||
});
|
||||
|
||||
add(
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
purple: node.children && codeCrumbsMinimize,
|
||||
name: node.data.name,
|
||||
onClick() {
|
||||
onFileSelect(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
add(
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
purple: node.children && codeCrumbsMinimize,
|
||||
onClick() {
|
||||
dependenciesDiagramOn && onFileIconClick(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.data.type === DIR_NODE_TYPE) {
|
||||
drawDot(secondaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn
|
||||
});
|
||||
|
||||
add(
|
||||
drawFolderText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
name: node.data.name,
|
||||
disabled: dependenciesDiagramOn
|
||||
})
|
||||
);
|
||||
add(
|
||||
drawFolderIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn,
|
||||
closed: closedFolders[node.data.path],
|
||||
onClick() {
|
||||
onFolderClick(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
drawSourceEdge(secondaryDraw, shiftToCenterPoint, {
|
||||
disabled: dependenciesDiagramOn,
|
||||
target: {
|
||||
x: nX,
|
||||
y: nY
|
||||
},
|
||||
source: {
|
||||
x: pX,
|
||||
y: pY
|
||||
},
|
||||
singleChild: parent.children.length === 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
if (node.data.type === FILE_NODE_TYPE) {
|
||||
drawDot(secondaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn
|
||||
});
|
||||
|
||||
add(
|
||||
drawFileText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
purple: node.children && codeCrumbsMinimize,
|
||||
name: node.data.name,
|
||||
onClick() {
|
||||
onFileSelect(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
add(
|
||||
drawFileIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
purple: node.children && codeCrumbsMinimize,
|
||||
onClick() {
|
||||
dependenciesDiagramOn && onFileIconClick(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.data.type === DIR_NODE_TYPE) {
|
||||
drawDot(secondaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn
|
||||
});
|
||||
|
||||
add(
|
||||
drawFolderText(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
name: node.data.name,
|
||||
disabled: dependenciesDiagramOn
|
||||
})
|
||||
);
|
||||
add(
|
||||
drawFolderIcon(primaryDraw, shiftToCenterPoint, {
|
||||
x: nX,
|
||||
y: nY,
|
||||
disabled: dependenciesDiagramOn,
|
||||
closed: closedFolders[node.data.path],
|
||||
onClick() {
|
||||
onFolderClick(node.data);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default withSvgDraw(SourceTree);
|
||||
|
|
|
|||
|
|
@ -5,174 +5,136 @@ import { BLUE_COLOR, PURPLE_COLOR, SYMBOL_WIDTH } from '../../store/constants';
|
|||
//create object instead
|
||||
const ICONS_DIR = 'resources/';
|
||||
|
||||
export const drawDot = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, disabled, highlighted }
|
||||
) => {
|
||||
const radius = 5;
|
||||
const halfRadius = radius / 2;
|
||||
const circlePoint = shiftToCenterPoint(x - halfRadius, y - halfRadius);
|
||||
export const drawDot = (draw, shiftToCenterPoint, { x, y, disabled, highlighted }) => {
|
||||
const radius = 5;
|
||||
const halfRadius = radius / 2;
|
||||
const circlePoint = shiftToCenterPoint(x - halfRadius, y - halfRadius);
|
||||
|
||||
let color = '#BFBFBF';
|
||||
if (disabled) {
|
||||
color = '#ccc';
|
||||
}
|
||||
if (highlighted) {
|
||||
color = BLUE_COLOR;
|
||||
}
|
||||
let color = '#BFBFBF';
|
||||
if (disabled) {
|
||||
color = '#ccc';
|
||||
}
|
||||
if (highlighted) {
|
||||
color = BLUE_COLOR;
|
||||
}
|
||||
|
||||
return draw
|
||||
.circle(radius)
|
||||
.fill(color)
|
||||
.move(circlePoint.x, circlePoint.y);
|
||||
return draw
|
||||
.circle(radius)
|
||||
.fill(color)
|
||||
.move(circlePoint.x, circlePoint.y);
|
||||
};
|
||||
|
||||
export const drawSourceEdge = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ target, source, disabled, singleChild }
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ target, source, disabled, singleChild }
|
||||
) => {
|
||||
const edgeTurnDistance = 20;
|
||||
const edgeTurnDistance = 20;
|
||||
|
||||
const START_PT = shiftToCenterPoint(source.x, source.y);
|
||||
const P2 = shiftToCenterPoint(target.x - edgeTurnDistance, source.y);
|
||||
const P3 = shiftToCenterPoint(target.x - edgeTurnDistance, target.y);
|
||||
const END_PT = shiftToCenterPoint(target.x, target.y);
|
||||
const START_PT = shiftToCenterPoint(source.x, source.y);
|
||||
const P2 = shiftToCenterPoint(target.x - edgeTurnDistance, source.y);
|
||||
const P3 = shiftToCenterPoint(target.x - edgeTurnDistance, target.y);
|
||||
const END_PT = shiftToCenterPoint(target.x, target.y);
|
||||
|
||||
const points = singleChild
|
||||
? [[START_PT.x, START_PT.y], [END_PT.x, END_PT.y]]
|
||||
: [
|
||||
[START_PT.x, START_PT.y],
|
||||
[P2.x, P2.y],
|
||||
[P3.x, P3.y],
|
||||
[END_PT.x, END_PT.y]
|
||||
];
|
||||
const points = singleChild
|
||||
? [[START_PT.x, START_PT.y], [END_PT.x, END_PT.y]]
|
||||
: [[START_PT.x, START_PT.y], [P2.x, P2.y], [P3.x, P3.y], [END_PT.x, END_PT.y]];
|
||||
|
||||
const polyline = draw.polyline(points);
|
||||
const polyline = draw.polyline(points);
|
||||
|
||||
const color = !disabled ? '#BFBFBF' : '#ccc';
|
||||
polyline.fill('none').stroke({
|
||||
color
|
||||
});
|
||||
|
||||
return polyline;
|
||||
};
|
||||
|
||||
export const drawFileText = (draw, shiftToCenterPoint, { x, y, purple, name = '', onClick }) => {
|
||||
const text = draw.text(name);
|
||||
text.font({ fill: purple ? PURPLE_COLOR : '#595959', family: 'Menlo' });
|
||||
|
||||
const fileTextPointShiftX = 16;
|
||||
const fileTextPointShiftY = 8;
|
||||
const fileTextPoint = shiftToCenterPoint(x + fileTextPointShiftX, y - fileTextPointShiftY);
|
||||
text.move(fileTextPoint.x, fileTextPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
text.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
export const drawFileIcon = (draw, shiftToCenterPoint, { x, y, purple, onClick }) => {
|
||||
const fileIconPath = ICONS_DIR + (purple ? 'js-file-purple.svg' : 'js-file.svg');
|
||||
const fileIconSize = 15;
|
||||
const fileIconPointShiftX = 2;
|
||||
const fileIconPointShiftY = 10;
|
||||
const fileIconPoint = shiftToCenterPoint(x + fileIconPointShiftX, y - fileIconPointShiftY);
|
||||
|
||||
const icon = draw
|
||||
.image(fileIconPath, fileIconSize, fileIconSize)
|
||||
.move(fileIconPoint.x, fileIconPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
icon.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
return icon;
|
||||
};
|
||||
|
||||
export const drawFolderText = (draw, shiftToCenterPoint, { x, y, name = '', disabled }) => {
|
||||
const folderTextPointShiftX = 20;
|
||||
const folderTextPointShiftY = 16;
|
||||
|
||||
const folderTextPoint = shiftToCenterPoint(x + folderTextPointShiftX, y - folderTextPointShiftY);
|
||||
|
||||
const fill = !disabled ? '#595959' : '#A9A8A8';
|
||||
const text = draw.text(name);
|
||||
|
||||
text.font({ fill, family: 'Menlo' });
|
||||
text.move(folderTextPoint.x, folderTextPoint.y);
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
export const drawFolderIcon = (draw, shiftToCenterPoint, { x, y, disabled, closed, onClick }) => {
|
||||
const folderIconPath = `${ICONS_DIR}${closed ? 'closed-' : ''}folder${
|
||||
disabled ? '-disabled' : ''
|
||||
}.svg`;
|
||||
|
||||
const folderIconSize = closed ? 14 : 15;
|
||||
const folderIconPointShiftX = closed ? 3 : 3;
|
||||
const folderIconPointShiftY = closed ? 16 : 17;
|
||||
const folderIconPoint = shiftToCenterPoint(x + folderIconPointShiftX, y - folderIconPointShiftY);
|
||||
|
||||
let polyline = null;
|
||||
if (closed) {
|
||||
polyline = draw.polyline([
|
||||
folderIconPoint.x - 1,
|
||||
folderIconPoint.y + 16,
|
||||
folderIconPoint.x + 16,
|
||||
folderIconPoint.y + 16,
|
||||
folderIconPoint.x + 16,
|
||||
folderIconPoint.y + 14
|
||||
]);
|
||||
|
||||
const color = !disabled ? '#BFBFBF' : '#ccc';
|
||||
polyline.fill('none').stroke({
|
||||
color
|
||||
color
|
||||
});
|
||||
}
|
||||
|
||||
return polyline;
|
||||
};
|
||||
|
||||
export const drawFileText = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, purple, name = '', onClick }
|
||||
) => {
|
||||
const text = draw.text(name);
|
||||
text.font({ fill: purple ? PURPLE_COLOR : '#595959', family: 'Menlo' });
|
||||
|
||||
const fileTextPointShiftX = 16;
|
||||
const fileTextPointShiftY = 8;
|
||||
const fileTextPoint = shiftToCenterPoint(
|
||||
x + fileTextPointShiftX,
|
||||
y - fileTextPointShiftY
|
||||
);
|
||||
text.move(fileTextPoint.x, fileTextPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
text.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
export const drawFileIcon = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, purple, onClick }
|
||||
) => {
|
||||
const fileIconPath =
|
||||
ICONS_DIR + (purple ? 'js-file-purple.svg' : 'js-file.svg');
|
||||
const fileIconSize = 15;
|
||||
const fileIconPointShiftX = 2;
|
||||
const fileIconPointShiftY = 10;
|
||||
const fileIconPoint = shiftToCenterPoint(
|
||||
x + fileIconPointShiftX,
|
||||
y - fileIconPointShiftY
|
||||
);
|
||||
|
||||
const icon = draw
|
||||
.image(fileIconPath, fileIconSize, fileIconSize)
|
||||
.move(fileIconPoint.x, fileIconPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
icon.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
return icon;
|
||||
};
|
||||
|
||||
export const drawFolderText = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, name = '', disabled }
|
||||
) => {
|
||||
const folderTextPointShiftX = 20;
|
||||
const folderTextPointShiftY = 16;
|
||||
|
||||
const folderTextPoint = shiftToCenterPoint(
|
||||
x + folderTextPointShiftX,
|
||||
y - folderTextPointShiftY
|
||||
);
|
||||
|
||||
const fill = !disabled ? '#595959' : '#A9A8A8';
|
||||
const text = draw.text(name);
|
||||
|
||||
text.font({ fill, family: 'Menlo' });
|
||||
text.move(folderTextPoint.x, folderTextPoint.y);
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
export const drawFolderIcon = (
|
||||
draw,
|
||||
shiftToCenterPoint,
|
||||
{ x, y, disabled, closed, onClick }
|
||||
) => {
|
||||
const folderIconPath = `${ICONS_DIR}${closed ? 'closed-' : ''}folder${
|
||||
disabled ? '-disabled' : ''
|
||||
}.svg`;
|
||||
|
||||
const folderIconSize = closed ? 14 : 15;
|
||||
const folderIconPointShiftX = closed ? 3 : 3;
|
||||
const folderIconPointShiftY = closed ? 16 : 17;
|
||||
const folderIconPoint = shiftToCenterPoint(
|
||||
x + folderIconPointShiftX,
|
||||
y - folderIconPointShiftY
|
||||
);
|
||||
|
||||
let polyline = null;
|
||||
if (closed) {
|
||||
polyline = draw.polyline([
|
||||
folderIconPoint.x - 1,
|
||||
folderIconPoint.y + 16,
|
||||
folderIconPoint.x + 16,
|
||||
folderIconPoint.y + 16,
|
||||
folderIconPoint.x + 16,
|
||||
folderIconPoint.y + 14
|
||||
]);
|
||||
|
||||
const color = !disabled ? '#BFBFBF' : '#ccc';
|
||||
polyline.fill('none').stroke({
|
||||
color
|
||||
});
|
||||
}
|
||||
|
||||
const icon = draw
|
||||
.image(folderIconPath, folderIconSize, folderIconSize)
|
||||
.move(folderIconPoint.x, folderIconPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
icon.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
if (!polyline) return icon;
|
||||
|
||||
return [icon, polyline];
|
||||
const icon = draw
|
||||
.image(folderIconPath, folderIconSize, folderIconSize)
|
||||
.move(folderIconPoint.x, folderIconPoint.y);
|
||||
|
||||
if (onClick) {
|
||||
icon.style({ cursor: 'pointer' }).on('click', onClick);
|
||||
}
|
||||
|
||||
if (!polyline) return icon;
|
||||
|
||||
return [icon, polyline];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,118 +5,118 @@ import CodeCrumbsTree from './CodeCrumbsTree/CodeCrumbsTree';
|
|||
import './TreeDiagram.css';
|
||||
|
||||
class TreeDiagram extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ layersReady: true });
|
||||
}
|
||||
componentDidMount() {
|
||||
this.setState({ layersReady: true });
|
||||
}
|
||||
|
||||
//cc: layers
|
||||
renderLayers() {
|
||||
return (
|
||||
<div className="TreeDiagram-layers">
|
||||
<div
|
||||
data-name="sourceEdgesLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.sourceEdgesLayer = ref)}
|
||||
/>
|
||||
<div
|
||||
data-name="dependenciesEdgesLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.dependenciesEdgesLayer = ref)}
|
||||
/>
|
||||
<div
|
||||
data-name="iconsAndTextLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.iconsAndTextLayer = ref)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
//cc: layers
|
||||
renderLayers() {
|
||||
return (
|
||||
<div className="TreeDiagram-layers">
|
||||
<div
|
||||
data-name="sourceEdgesLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.sourceEdgesLayer = ref)}
|
||||
/>
|
||||
<div
|
||||
data-name="dependenciesEdgesLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.dependenciesEdgesLayer = ref)}
|
||||
/>
|
||||
<div
|
||||
data-name="iconsAndTextLayer"
|
||||
className="TreeDiagram-layer"
|
||||
ref={ref => (this.iconsAndTextLayer = ref)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDiagrams() {
|
||||
const {
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint,
|
||||
renderDiagrams() {
|
||||
const {
|
||||
filesTreeLayoutNodes,
|
||||
dependenciesList,
|
||||
closedFolders,
|
||||
dependenciesEntryPoint,
|
||||
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
dependenciesShowOneModule,
|
||||
codeCrumbsDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails,
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
dependenciesShowOneModule,
|
||||
codeCrumbsDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails,
|
||||
|
||||
onFileSelect,
|
||||
onFileIconClick,
|
||||
onFolderClick,
|
||||
onCodeCrumbSelect
|
||||
} = this.props;
|
||||
onFileSelect,
|
||||
onFileIconClick,
|
||||
onFolderClick,
|
||||
onCodeCrumbSelect
|
||||
} = this.props;
|
||||
|
||||
const sharedProps = {
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails
|
||||
};
|
||||
const sharedProps = {
|
||||
sourceDiagramOn,
|
||||
dependenciesDiagramOn,
|
||||
codeCrumbsDiagramOn,
|
||||
codeCrumbsMinimize,
|
||||
codeCrumbsDetails
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{filesTreeLayoutNodes &&
|
||||
sourceDiagramOn && (
|
||||
<SourceTree
|
||||
layoutNodes={filesTreeLayoutNodes}
|
||||
closedFolders={closedFolders}
|
||||
secondaryLayer={this.sourceEdgesLayer}
|
||||
primaryLayer={this.iconsAndTextLayer}
|
||||
onFileSelect={onFileSelect}
|
||||
onFileIconClick={onFileIconClick}
|
||||
onFolderClick={onFolderClick}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
return (
|
||||
<React.Fragment>
|
||||
{filesTreeLayoutNodes &&
|
||||
sourceDiagramOn && (
|
||||
<SourceTree
|
||||
layoutNodes={filesTreeLayoutNodes}
|
||||
closedFolders={closedFolders}
|
||||
secondaryLayer={this.sourceEdgesLayer}
|
||||
primaryLayer={this.iconsAndTextLayer}
|
||||
onFileSelect={onFileSelect}
|
||||
onFileIconClick={onFileIconClick}
|
||||
onFolderClick={onFolderClick}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{dependenciesList &&
|
||||
filesTreeLayoutNodes &&
|
||||
dependenciesDiagramOn && (
|
||||
<DependenciesTree
|
||||
dependenciesList={dependenciesList}
|
||||
filesTreeLayoutNodes={filesTreeLayoutNodes}
|
||||
dependenciesEntryPoint={dependenciesEntryPoint}
|
||||
dependenciesShowOneModule={dependenciesShowOneModule}
|
||||
primaryLayer={this.dependenciesEdgesLayer}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
{dependenciesList &&
|
||||
filesTreeLayoutNodes &&
|
||||
dependenciesDiagramOn && (
|
||||
<DependenciesTree
|
||||
dependenciesList={dependenciesList}
|
||||
filesTreeLayoutNodes={filesTreeLayoutNodes}
|
||||
dependenciesEntryPoint={dependenciesEntryPoint}
|
||||
dependenciesShowOneModule={dependenciesShowOneModule}
|
||||
primaryLayer={this.dependenciesEdgesLayer}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{filesTreeLayoutNodes &&
|
||||
codeCrumbsDiagramOn && (
|
||||
<CodeCrumbsTree
|
||||
filesTreeLayoutNodes={filesTreeLayoutNodes}
|
||||
primaryLayer={this.iconsAndTextLayer}
|
||||
onCodeCrumbSelect={onCodeCrumbSelect}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
{filesTreeLayoutNodes &&
|
||||
codeCrumbsDiagramOn && (
|
||||
<CodeCrumbsTree
|
||||
filesTreeLayoutNodes={filesTreeLayoutNodes}
|
||||
primaryLayer={this.iconsAndTextLayer}
|
||||
onCodeCrumbSelect={onCodeCrumbSelect}
|
||||
{...sharedProps}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { layersReady } = this.state;
|
||||
render() {
|
||||
const { layersReady } = this.state;
|
||||
|
||||
return (
|
||||
<div className="TreeDiagram-container">
|
||||
{this.renderLayers()}
|
||||
{layersReady && this.renderDiagrams()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="TreeDiagram-container">
|
||||
{this.renderLayers()}
|
||||
{layersReady && this.renderDiagrams()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TreeDiagram;
|
||||
|
|
|
|||
|
|
@ -5,81 +5,80 @@ import { buildShiftToPoint } from '../../../../utils/geometry';
|
|||
const IconsAndTextLayer = 'iconsAndTextLayer';
|
||||
const cachedSvgDraws = {};
|
||||
|
||||
const BOX_SIZE = {W: 1000, H: 800};
|
||||
const BOX_SIZE = { W: 1000, H: 800 };
|
||||
const DOT = {
|
||||
x: 50,
|
||||
y: 500
|
||||
x: 50,
|
||||
y: 500
|
||||
};
|
||||
|
||||
const shiftToCenterPoint = buildShiftToPoint(DOT);
|
||||
|
||||
export const withSvgDraw = Component =>
|
||||
class extends React.Component {
|
||||
state = {};
|
||||
class extends React.Component {
|
||||
state = {};
|
||||
|
||||
createSvg(layer) {
|
||||
const { width = BOX_SIZE.W, height = BOX_SIZE.H } = this.props;
|
||||
createSvg(layer) {
|
||||
const { width = BOX_SIZE.W, height = BOX_SIZE.H } = this.props;
|
||||
|
||||
return SVG(layer).size(width, height);
|
||||
}
|
||||
return SVG(layer).size(width, height);
|
||||
}
|
||||
|
||||
getPrimaryDraw() {
|
||||
const { primaryLayer } = this.props;
|
||||
getPrimaryDraw() {
|
||||
const { primaryLayer } = this.props;
|
||||
|
||||
const primaryLayerName = primaryLayer.dataset.name;
|
||||
if (primaryLayerName !== IconsAndTextLayer) {
|
||||
return this.createSvg(primaryLayer);
|
||||
}
|
||||
const primaryLayerName = primaryLayer.dataset.name;
|
||||
if (primaryLayerName !== IconsAndTextLayer) {
|
||||
return this.createSvg(primaryLayer);
|
||||
}
|
||||
|
||||
if (cachedSvgDraws[primaryLayerName]) {
|
||||
return cachedSvgDraws[primaryLayerName];
|
||||
}
|
||||
if (cachedSvgDraws[primaryLayerName]) {
|
||||
return cachedSvgDraws[primaryLayerName];
|
||||
}
|
||||
|
||||
cachedSvgDraws[primaryLayerName] = this.createSvg(primaryLayer);
|
||||
return cachedSvgDraws[primaryLayerName];
|
||||
}
|
||||
cachedSvgDraws[primaryLayerName] = this.createSvg(primaryLayer);
|
||||
return cachedSvgDraws[primaryLayerName];
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { secondaryLayer } = this.props;
|
||||
componentDidMount() {
|
||||
const { secondaryLayer } = this.props;
|
||||
|
||||
let subState = {
|
||||
primaryDraw: this.getPrimaryDraw()
|
||||
};
|
||||
let subState = {
|
||||
primaryDraw: this.getPrimaryDraw()
|
||||
};
|
||||
|
||||
if (secondaryLayer) {
|
||||
subState = {
|
||||
...subState,
|
||||
secondaryDraw: this.createSvg(secondaryLayer)
|
||||
};
|
||||
}
|
||||
if (secondaryLayer) {
|
||||
subState = {
|
||||
...subState,
|
||||
secondaryDraw: this.createSvg(secondaryLayer)
|
||||
};
|
||||
}
|
||||
|
||||
this.setState(subState);
|
||||
}
|
||||
this.setState(subState);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { primaryLayer, secondaryLayer } = this.props;
|
||||
componentWillUnmount() {
|
||||
const { primaryLayer, secondaryLayer } = this.props;
|
||||
|
||||
if (primaryLayer.dataset.name !== IconsAndTextLayer) {
|
||||
primaryLayer.removeChild(this.state.primaryDraw.node);
|
||||
}
|
||||
if (primaryLayer.dataset.name !== IconsAndTextLayer) {
|
||||
primaryLayer.removeChild(this.state.primaryDraw.node);
|
||||
}
|
||||
|
||||
secondaryLayer &&
|
||||
secondaryLayer.removeChild(this.state.secondaryDraw.node);
|
||||
}
|
||||
secondaryLayer && secondaryLayer.removeChild(this.state.secondaryDraw.node);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { primaryDraw, secondaryDraw } = this.state;
|
||||
render() {
|
||||
const { primaryDraw, secondaryDraw } = this.state;
|
||||
|
||||
return (
|
||||
(primaryDraw && (
|
||||
<Component
|
||||
{...this.props}
|
||||
primaryDraw={primaryDraw}
|
||||
secondaryDraw={secondaryDraw}
|
||||
shiftToCenterPoint={shiftToCenterPoint}
|
||||
/>
|
||||
)) ||
|
||||
null
|
||||
);
|
||||
}
|
||||
};
|
||||
return (
|
||||
(primaryDraw && (
|
||||
<Component
|
||||
{...this.props}
|
||||
primaryDraw={primaryDraw}
|
||||
secondaryDraw={secondaryDraw}
|
||||
shiftToCenterPoint={shiftToCenterPoint}
|
||||
/>
|
||||
)) ||
|
||||
null
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
export const createSet = draw => {
|
||||
const drawSet = draw.set();
|
||||
const drawSet = draw.set();
|
||||
|
||||
return {
|
||||
add(list) {
|
||||
drawSet.add.apply(drawSet, [].concat(list));
|
||||
},
|
||||
clearAll() {
|
||||
drawSet.each(function() {
|
||||
this.off();
|
||||
this.remove();
|
||||
});
|
||||
drawSet.clear();
|
||||
}
|
||||
};
|
||||
return {
|
||||
add(list) {
|
||||
drawSet.add.apply(drawSet, [].concat(list));
|
||||
},
|
||||
clearAll() {
|
||||
drawSet.each(function() {
|
||||
this.off();
|
||||
this.remove();
|
||||
});
|
||||
drawSet.clear();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ export const BLUE_COLOR = '#1890ff';
|
|||
export const SYMBOL_WIDTH = 8.4;
|
||||
|
||||
export const LAYOUT_CONFIG = {
|
||||
symbolWidth: SYMBOL_WIDTH,
|
||||
nodeSizeX: 20,
|
||||
nodeSizeY: 60,
|
||||
spacing: 20
|
||||
};
|
||||
symbolWidth: SYMBOL_WIDTH,
|
||||
nodeSizeX: 20,
|
||||
nodeSizeY: 60,
|
||||
spacing: 20
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ const MOUNT_NODE_ID = 'mount-node';
|
|||
|
||||
const store = getStore();
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>,
|
||||
document.getElementById(MOUNT_NODE_ID)
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>,
|
||||
document.getElementById(MOUNT_NODE_ID)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ import dataBus from '../components/data-bus/store/reducer';
|
|||
import rootSaga from './sagas';
|
||||
|
||||
export default () => {
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
const store = createStore(
|
||||
combineReducers({
|
||||
viewSwitches,
|
||||
dataBus
|
||||
}),
|
||||
applyMiddleware(thunk, sagaMiddleware)
|
||||
);
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
const store = createStore(
|
||||
combineReducers({
|
||||
viewSwitches,
|
||||
dataBus
|
||||
}),
|
||||
applyMiddleware(thunk, sagaMiddleware)
|
||||
);
|
||||
|
||||
sagaMiddleware.run(rootSaga);
|
||||
return store;
|
||||
sagaMiddleware.run(rootSaga);
|
||||
return store;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,122 +2,108 @@ import every from 'lodash/every';
|
|||
import { put, takeEvery, select, all } from 'redux-saga/effects';
|
||||
import { ACTIONS as DATA_BUS_ACTIONS } from '../components/data-bus/store/constants';
|
||||
import {
|
||||
calcFilesTreeLayoutNodes,
|
||||
openAllFolders,
|
||||
closeAllFolders,
|
||||
setDependenciesEntryPoint
|
||||
calcFilesTreeLayoutNodes,
|
||||
openAllFolders,
|
||||
closeAllFolders,
|
||||
setDependenciesEntryPoint
|
||||
} from '../components/data-bus/store/actions';
|
||||
|
||||
import {
|
||||
ACTIONS as SWITCHES_ACTIONS,
|
||||
CONTROLS_KEYS
|
||||
ACTIONS as SWITCHES_ACTIONS,
|
||||
CONTROLS_KEYS
|
||||
} from '../components/controls/ViewSwitches/store/constants';
|
||||
import {
|
||||
setDisabledControl,
|
||||
toggleSwitch
|
||||
setDisabledControl,
|
||||
toggleSwitch
|
||||
} from '../components/controls/ViewSwitches/store/actions';
|
||||
|
||||
function* reactOnSwitchToggle(action) {
|
||||
const { switchKey } = action.payload;
|
||||
const { switchKey } = action.payload;
|
||||
|
||||
if (switchKey === CONTROLS_KEYS.CODE_CRUMBS) {
|
||||
yield put(calcFilesTreeLayoutNodes());
|
||||
}
|
||||
if (switchKey === CONTROLS_KEYS.CODE_CRUMBS) {
|
||||
yield put(calcFilesTreeLayoutNodes());
|
||||
}
|
||||
|
||||
if (switchKey === CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE) {
|
||||
const isDisabled = yield isDependenciesShowAllDisabled();
|
||||
yield put(
|
||||
setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, isDisabled)
|
||||
);
|
||||
}
|
||||
if (switchKey === CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE) {
|
||||
const isDisabled = yield isDependenciesShowAllDisabled();
|
||||
yield put(setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, isDisabled));
|
||||
}
|
||||
}
|
||||
|
||||
function* reactOnButtonAction(action) {
|
||||
const buttonKey = action.payload;
|
||||
const buttonKey = action.payload;
|
||||
|
||||
if (buttonKey === CONTROLS_KEYS.SOURCE_EXPAND_ALL) {
|
||||
return yield all([
|
||||
put(setDisabledControl(CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN)),
|
||||
put(openAllFolders()),
|
||||
put(calcFilesTreeLayoutNodes())
|
||||
]);
|
||||
}
|
||||
if (buttonKey === CONTROLS_KEYS.SOURCE_EXPAND_ALL) {
|
||||
return yield all([
|
||||
put(setDisabledControl(CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN)),
|
||||
put(openAllFolders()),
|
||||
put(calcFilesTreeLayoutNodes())
|
||||
]);
|
||||
}
|
||||
|
||||
if (buttonKey === CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN) {
|
||||
return yield all([
|
||||
put(setDisabledControl(CONTROLS_KEYS.SOURCE_EXPAND_ALL)),
|
||||
put(closeAllFolders()),
|
||||
put(calcFilesTreeLayoutNodes())
|
||||
]);
|
||||
}
|
||||
if (buttonKey === CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN) {
|
||||
return yield all([
|
||||
put(setDisabledControl(CONTROLS_KEYS.SOURCE_EXPAND_ALL)),
|
||||
put(closeAllFolders()),
|
||||
put(calcFilesTreeLayoutNodes())
|
||||
]);
|
||||
}
|
||||
|
||||
if (buttonKey === CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL) {
|
||||
return yield all([
|
||||
put(toggleSwitch(CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE)),
|
||||
put(setDependenciesEntryPoint(null))
|
||||
]);
|
||||
}
|
||||
if (buttonKey === CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL) {
|
||||
return yield all([
|
||||
put(toggleSwitch(CONTROLS_KEYS.DEPENDENCIES_SHOW_ONE_MODULE)),
|
||||
put(setDependenciesEntryPoint(null))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function* reactOnToggledFolder(action) {
|
||||
const dataBusState = yield select(state => state.dataBus);
|
||||
const { closedFolders, firstLevelFolders } = dataBusState;
|
||||
const dataBusState = yield select(state => state.dataBus);
|
||||
const { closedFolders, firstLevelFolders } = dataBusState;
|
||||
|
||||
yield all([
|
||||
put(
|
||||
setDisabledControl(
|
||||
CONTROLS_KEYS.SOURCE_EXPAND_ALL,
|
||||
every(Object.keys(closedFolders), item => !closedFolders[item])
|
||||
)
|
||||
),
|
||||
yield all([
|
||||
put(
|
||||
setDisabledControl(
|
||||
CONTROLS_KEYS.SOURCE_EXPAND_ALL,
|
||||
every(Object.keys(closedFolders), item => !closedFolders[item])
|
||||
)
|
||||
),
|
||||
|
||||
put(
|
||||
setDisabledControl(
|
||||
CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN,
|
||||
every(
|
||||
Object.keys(firstLevelFolders),
|
||||
item => closedFolders[item]
|
||||
)
|
||||
)
|
||||
)
|
||||
]);
|
||||
put(
|
||||
setDisabledControl(
|
||||
CONTROLS_KEYS.SOURCE_COLLAPSE_TO_MIN,
|
||||
every(Object.keys(firstLevelFolders), item => closedFolders[item])
|
||||
)
|
||||
)
|
||||
]);
|
||||
|
||||
yield put(calcFilesTreeLayoutNodes());
|
||||
yield put(calcFilesTreeLayoutNodes());
|
||||
}
|
||||
|
||||
function* reactDependenciesEntryPointChange(action) {
|
||||
if (!action.payload) {
|
||||
return yield put(
|
||||
setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, true)
|
||||
);
|
||||
}
|
||||
if (!action.payload) {
|
||||
return yield put(setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, true));
|
||||
}
|
||||
|
||||
const isDisabled = yield isDependenciesShowAllDisabled();
|
||||
yield put(
|
||||
setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, isDisabled)
|
||||
);
|
||||
const isDisabled = yield isDependenciesShowAllDisabled();
|
||||
yield put(setDisabledControl(CONTROLS_KEYS.DEPENDENCIES_SHOW_ALL, isDisabled));
|
||||
}
|
||||
|
||||
function* isDependenciesShowAllDisabled() {
|
||||
const isRoot = yield select(
|
||||
state => state.dataBus.isCurrentDependenciesEntryPointRoot
|
||||
);
|
||||
const isRoot = yield select(state => state.dataBus.isCurrentDependenciesEntryPointRoot);
|
||||
|
||||
const dependenciesShowOneModule = yield select(
|
||||
state => state.viewSwitches.checkedState.dependenciesShowOneModule
|
||||
);
|
||||
const dependenciesShowOneModule = yield select(
|
||||
state => state.viewSwitches.checkedState.dependenciesShowOneModule
|
||||
);
|
||||
|
||||
return isRoot && !dependenciesShowOneModule;
|
||||
return isRoot && !dependenciesShowOneModule;
|
||||
}
|
||||
|
||||
export default function* rootSaga() {
|
||||
yield all([
|
||||
takeEvery(SWITCHES_ACTIONS.TOGGLE_SWITCH, reactOnSwitchToggle),
|
||||
takeEvery(SWITCHES_ACTIONS.FIRE_BUTTON_ACTION, reactOnButtonAction),
|
||||
takeEvery(DATA_BUS_ACTIONS.TOGGLE_FOLDER, reactOnToggledFolder),
|
||||
takeEvery(
|
||||
DATA_BUS_ACTIONS.SET_DEPENDENCIES_ENTRY_POINT,
|
||||
reactDependenciesEntryPointChange
|
||||
)
|
||||
]);
|
||||
yield all([
|
||||
takeEvery(SWITCHES_ACTIONS.TOGGLE_SWITCH, reactOnSwitchToggle),
|
||||
takeEvery(SWITCHES_ACTIONS.FIRE_BUTTON_ACTION, reactOnButtonAction),
|
||||
takeEvery(DATA_BUS_ACTIONS.TOGGLE_FOLDER, reactOnToggledFolder),
|
||||
takeEvery(DATA_BUS_ACTIONS.SET_DEPENDENCIES_ENTRY_POINT, reactDependenciesEntryPointChange)
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
export const createConnection = (onMessage, route = 'ws://127.0.0.1:2018/') => {
|
||||
const ws = new WebSocket(route);
|
||||
ws.onmessage = event => {
|
||||
onMessage(JSON.parse(event.data));
|
||||
};
|
||||
const ws = new WebSocket(route);
|
||||
ws.onmessage = event => {
|
||||
onMessage(JSON.parse(event.data));
|
||||
};
|
||||
|
||||
return msg => {
|
||||
try {
|
||||
ws.send(msg);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
return msg => {
|
||||
try {
|
||||
ws.send(msg);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,56 +3,53 @@ import babelTraverse from 'babel-traverse';
|
|||
import * as d3flextree from 'd3-flextree';
|
||||
import SVG from 'svg.js';
|
||||
|
||||
|
||||
const astTest = () => {
|
||||
const ast = babylon.parse(`
|
||||
const ast = babylon.parse(`
|
||||
//codecrumb
|
||||
var a = 12;
|
||||
|
||||
var b = 8;//cc//aa
|
||||
`);
|
||||
|
||||
babelTraverse(ast, {
|
||||
enter(path) {
|
||||
if (path.node && path.node.leadingComments || path.node.trailingComments) {
|
||||
//debugger
|
||||
console.log(path.node.leadingComments, path.node.trailingComments);
|
||||
}
|
||||
}
|
||||
});
|
||||
babelTraverse(ast, {
|
||||
enter(path) {
|
||||
if ((path.node && path.node.leadingComments) || path.node.trailingComments) {
|
||||
//debugger
|
||||
console.log(path.node.leadingComments, path.node.trailingComments);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const d3test = treeData => {
|
||||
const draw = SVG('drawing').size(500, 500);
|
||||
const draw = SVG('drawing').size(500, 500);
|
||||
|
||||
const layout = d3flextree.flextree({
|
||||
children: data => {
|
||||
return data.children;
|
||||
},
|
||||
nodeSize: node => [node.data.name.length, 40],
|
||||
spacing: (nodeA, nodeB) => 150
|
||||
});
|
||||
const tree = layout.hierarchy(treeData);
|
||||
const lt = layout(tree);
|
||||
const layout = d3flextree.flextree({
|
||||
children: data => {
|
||||
return data.children;
|
||||
},
|
||||
nodeSize: node => [node.data.name.length, 40],
|
||||
spacing: (nodeA, nodeB) => 150
|
||||
});
|
||||
const tree = layout.hierarchy(treeData);
|
||||
const lt = layout(tree);
|
||||
|
||||
lt.each(node => {
|
||||
draw
|
||||
.circle(10)
|
||||
.attr({ fill: '#f06' })
|
||||
.move(node.x + 200, node.y + 200);
|
||||
lt.each(node => {
|
||||
draw
|
||||
.circle(10)
|
||||
.attr({ fill: '#f06' })
|
||||
.move(node.x + 200, node.y + 200);
|
||||
|
||||
draw.text(node.data.name).move(node.x + 200, node.y + 200);
|
||||
draw.text(node.data.name).move(node.x + 200, node.y + 200);
|
||||
|
||||
if (node.parent) {
|
||||
let p = node.parent;
|
||||
draw
|
||||
.line(p.x + 200, p.y + 200, node.x + 200, node.y + 200)
|
||||
.stroke({ width: 1 });
|
||||
}
|
||||
});
|
||||
if (node.parent) {
|
||||
let p = node.parent;
|
||||
draw.line(p.x + 200, p.y + 200, node.x + 200, node.y + 200).stroke({ width: 1 });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default p => {
|
||||
//astTest();
|
||||
//d3test(p);
|
||||
//astTest();
|
||||
//d3test(p);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export const buildShiftToPoint = shift => (x, y) => ({
|
||||
x: shift.x + x,
|
||||
y: shift.y + y
|
||||
x: shift.x + x,
|
||||
y: shift.y + y
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,45 @@
|
|||
|
||||
export const getCurvedPath = (points, theme) => {
|
||||
const pointStr = points
|
||||
.map((point, i) => {
|
||||
if (!i) return `M${point.x}, ${point.y}`;
|
||||
const pointStr = points
|
||||
.map((point, i) => {
|
||||
if (!i) return `M${point.x}, ${point.y}`;
|
||||
|
||||
let previousPoint = points[i - 1];
|
||||
let previousPoint = points[i - 1];
|
||||
|
||||
if (i <= 1) {
|
||||
return getLinePointStr(point, previousPoint, theme.curveTurnRadius);
|
||||
}
|
||||
if (i <= 1) {
|
||||
return getLinePointStr(point, previousPoint, theme.curveTurnRadius);
|
||||
}
|
||||
|
||||
return `Q${previousPoint.x} ${previousPoint.y}
|
||||
return `Q${previousPoint.x} ${previousPoint.y}
|
||||
${getArcEndPointStr(point, previousPoint, theme.curveTurnRadius)}
|
||||
${getLinePointStr(point, previousPoint, 2 * theme.curveTurnRadius)}`;
|
||||
})
|
||||
.join(' ');
|
||||
})
|
||||
.join(' ');
|
||||
|
||||
return pointStr;
|
||||
return pointStr;
|
||||
};
|
||||
|
||||
const getLinePointStr = (point, previousPoint, radius) => {
|
||||
if (point.x === previousPoint.x) {
|
||||
return `L${point.x} ${getShiftedByArcNextPointValue(point.y, previousPoint.y, radius)}`;
|
||||
}
|
||||
if (point.x === previousPoint.x) {
|
||||
return `L${point.x} ${getShiftedByArcNextPointValue(point.y, previousPoint.y, radius)}`;
|
||||
}
|
||||
|
||||
if (point.y === previousPoint.y) {
|
||||
return `L${getShiftedByArcNextPointValue(point.x, previousPoint.x, radius)} ${point.y} `;
|
||||
}
|
||||
if (point.y === previousPoint.y) {
|
||||
return `L${getShiftedByArcNextPointValue(point.x, previousPoint.x, radius)} ${point.y} `;
|
||||
}
|
||||
};
|
||||
|
||||
const getShiftedByArcNextPointValue = (pointValue, previousPointValue, radius) =>
|
||||
pointValue > previousPointValue ? pointValue - radius : pointValue + radius;
|
||||
pointValue > previousPointValue ? pointValue - radius : pointValue + radius;
|
||||
|
||||
const getArcEndPointStr = (point, previousPoint, radius) => {
|
||||
if (point.x === previousPoint.x) {
|
||||
return `${previousPoint.x} ${getArcEndPointValue(point.y, previousPoint.y, radius)}`;
|
||||
}
|
||||
if (point.x === previousPoint.x) {
|
||||
return `${previousPoint.x} ${getArcEndPointValue(point.y, previousPoint.y, radius)}`;
|
||||
}
|
||||
|
||||
if (point.y === previousPoint.y) {
|
||||
return `${getArcEndPointValue(point.x, previousPoint.x, radius)} ${previousPoint.y}`;
|
||||
}
|
||||
if (point.y === previousPoint.y) {
|
||||
return `${getArcEndPointValue(point.x, previousPoint.x, radius)} ${previousPoint.y}`;
|
||||
}
|
||||
};
|
||||
|
||||
const getArcEndPointValue = (pointValue, previousPointValue, radius) =>
|
||||
pointValue > previousPointValue ? previousPointValue + radius : previousPointValue - radius;
|
||||
pointValue > previousPointValue ? previousPointValue + radius : previousPointValue - radius;
|
||||
|
|
|
|||
|
|
@ -3,55 +3,49 @@ import { FILE_NODE_TYPE, DIR_NODE_TYPE } from '../../../shared/constants';
|
|||
import { LAYOUT_CONFIG } from '../components/tree-diagram/store/constants';
|
||||
|
||||
export const getTreeLayout = (
|
||||
treeData,
|
||||
{ includeFileChildren, config = LAYOUT_CONFIG, closedFolders }
|
||||
treeData,
|
||||
{ includeFileChildren, config = LAYOUT_CONFIG, closedFolders }
|
||||
) => {
|
||||
const layoutStructure = d3FlexTree.flextree({
|
||||
children: data => {
|
||||
if (data.type === DIR_NODE_TYPE) {
|
||||
return !closedFolders[data.path] ? data.children : [];
|
||||
}
|
||||
const layoutStructure = d3FlexTree.flextree({
|
||||
children: data => {
|
||||
if (data.type === DIR_NODE_TYPE) {
|
||||
return !closedFolders[data.path] ? data.children : [];
|
||||
}
|
||||
|
||||
return includeFileChildren ? data.children : [];
|
||||
},
|
||||
nodeSize: node => {
|
||||
let nameLength = node.data.name.length;
|
||||
return includeFileChildren ? data.children : [];
|
||||
},
|
||||
nodeSize: node => {
|
||||
let nameLength = node.data.name.length;
|
||||
|
||||
//cc: layout calc
|
||||
if (node.parent && node.data.type === DIR_NODE_TYPE) {
|
||||
const children = node.parent.children;
|
||||
nameLength = children.reduce((max, item) => {
|
||||
if (
|
||||
item.data.type === DIR_NODE_TYPE &&
|
||||
item.data.name.length > max
|
||||
) {
|
||||
return item.data.name.length;
|
||||
}
|
||||
//cc: layout calc
|
||||
if (node.parent && node.data.type === DIR_NODE_TYPE) {
|
||||
const children = node.parent.children;
|
||||
nameLength = children.reduce((max, item) => {
|
||||
if (item.data.type === DIR_NODE_TYPE && item.data.name.length > max) {
|
||||
return item.data.name.length;
|
||||
}
|
||||
|
||||
return max;
|
||||
}, 0);
|
||||
}
|
||||
return max;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
return [
|
||||
config.nodeSizeX,
|
||||
nameLength * config.symbolWidth + config.nodeSizeY
|
||||
];
|
||||
},
|
||||
spacing: (nodeA, nodeB) => config.spacing
|
||||
});
|
||||
return [config.nodeSizeX, nameLength * config.symbolWidth + config.nodeSizeY];
|
||||
},
|
||||
spacing: (nodeA, nodeB) => config.spacing
|
||||
});
|
||||
|
||||
const tree = layoutStructure.hierarchy(treeData);
|
||||
return layoutStructure(tree);
|
||||
const tree = layoutStructure.hierarchy(treeData);
|
||||
return layoutStructure(tree);
|
||||
};
|
||||
|
||||
export const getFilesList = layoutNodes => {
|
||||
const list = [];
|
||||
const list = [];
|
||||
|
||||
layoutNodes.each(node => {
|
||||
if (node.data && node.data.type === FILE_NODE_TYPE) {
|
||||
list.push(node);
|
||||
}
|
||||
});
|
||||
layoutNodes.each(node => {
|
||||
if (node.data && node.data.type === FILE_NODE_TYPE) {
|
||||
list.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
return list;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue