Skip to content

Commit b7f16f3

Browse files
feat: add external edges for codecrumbs
1 parent 012d8c8 commit b7f16f3

14 files changed

Lines changed: 231 additions & 67 deletions

File tree

example-project/src-client/auth/reducer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function authReducer(state = new AuthState(), {payload, type}) {
1313
case INIT_AUTH:
1414
case SIGN_IN_SUCCESS:
1515
return state.merge({
16-
authenticated: !!payload, // cc:signin#2;toggle 'authenticated' flag
16+
authenticated: !!payload, // cc:signin#5;toggle 'authenticated' flag
1717
id: payload ? payload.uid : null
1818
});
1919

example-project/src-client/views/components/require-auth-route/require-auth-route.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { Route, Redirect } from 'react-router-dom'
33

4-
//cc:signin#3;enable route;+6
4+
//cc:signin#6;enable route;+6
55
const RequireAuthRoute = ({component: Component, authenticated, ...rest}) => (
66
<Route
77
{...rest}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//cc:signin#2;send request
2+
3+
//cc:signin#4;respond to client
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//cc:signin#3;updare seesion

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
},
1010
"scripts": {
1111
"start": "yarn client-dev & yarn server-dev",
12+
"server:one": "node src/index.dev.js",
1213
"server:two": "node src/index.dev.js two",
13-
"start:demo": "node src/index.dev.js",
1414
"client-dev": "cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev",
1515
"server-dev": "nodemon src/index.dev.js",
1616
"server-debug": "nodemon --inspect src/index.dev.js",

src/public/dist/local/bundle/main.bundle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46889,7 +46889,7 @@ module.exports = function(originalModule) {
4688946889
/*! exports provided: name, version, author, license, repository, scripts, bin, dependencies, devDependencies, nodemonConfig, husky, default */
4689046890
/***/ (function(module) {
4689146891

46892-
module.exports = {"name":"codecrumbs","version":"1.0.12-alpha","author":"Bohdan Liashenko","license":"BSD-3-Clause","repository":{"type":"git","url":"https://github.com/Bogdan-Lyashenko/codecrumbs.git"},"scripts":{"start":"yarn client-dev & yarn server-dev","server:two":"node src/index.dev.js two","start:demo":"node src/index.dev.js","client-dev":"cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev","server-dev":"nodemon src/index.dev.js","server-debug":"nodemon --inspect src/index.dev.js","build":"cd src/public && webpack --config webpack.prod.js --progress --colors","start:standalone":"cd src/public/dist/standalone && http-server","pretty":"prettier --write \"./src/public/js/**/*.js\""},"bin":{"codecrumbs":"./cli/index.cli.js"},"dependencies":{"@babel/parser":"^7.1.2","@babel/polyfill":"^7.0.0","@babel/traverse":"^7.1.0","antd":"^3.9.2","chokidar":"^2.0.3","classnames":"^2.2.6","colors":"^1.3.2","commander":"^2.19.0","copy-text-to-clipboard":"^1.0.4","d3-flextree":"^2.1.1","directory-tree":"^2.1.0","file-saver":"^2.0.0","http-server":"^0.11.1","js2flowchart":"^1.1.7","lodash":"^4.17.10","lodash.debounce":"^4.0.8","madge":"^3.3.0","portscanner":"^2.2.0","react":"^16.7.0","react-dom":"^16.7.0","react-draggable":"^3.0.5","react-redux":"^5.0.7","react-syntax-highlighter":"8.0.1","redux":"^4.0.0","redux-persist":"^5.10.0","redux-saga":"^0.16.0","redux-thunk":"^2.2.0","reselect":"^4.0.0","websocket":"^1.0.26"},"devDependencies":{"@babel/core":"^7.1.2","@babel/plugin-syntax-dynamic-import":"^7.2.0","@babel/preset-env":"^7.1.0","@babel/preset-react":"^7.0.0","@commitlint/cli":"^7.3.2","@commitlint/config-conventional":"^7.3.1","babel-loader":"^8.0.4","babel-plugin-import":"^1.9.1","css-loader":"^0.28.11","husky":"^1.3.1","node-sass":"^4.9.3","nodemon":"^1.18.7","prettier":"^1.14.0","sass-loader":"^7.1.0","style-loader":"^0.21.0","webpack":"^4.20.2","webpack-bundle-analyzer":"^3.0.3","webpack-cli":"^3.1.2","webpack-merge":"^4.1.5"},"nodemonConfig":{"ignore":["src/public/**/*.*"],"delay":"2500"},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}}};
46892+
module.exports = {"name":"codecrumbs","version":"1.0.12-alpha","author":"Bohdan Liashenko","license":"BSD-3-Clause","repository":{"type":"git","url":"https://github.com/Bogdan-Lyashenko/codecrumbs.git"},"scripts":{"start":"yarn client-dev & yarn server-dev","server:one":"node src/index.dev.js","server:two":"node src/index.dev.js two","client-dev":"cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev","server-dev":"nodemon src/index.dev.js","server-debug":"nodemon --inspect src/index.dev.js","build":"cd src/public && webpack --config webpack.prod.js --progress --colors","start:standalone":"cd src/public/dist/standalone && http-server","pretty":"prettier --write \"./src/public/js/**/*.js\""},"bin":{"codecrumbs":"./cli/index.cli.js"},"dependencies":{"@babel/parser":"^7.1.2","@babel/polyfill":"^7.0.0","@babel/traverse":"^7.1.0","antd":"^3.9.2","chokidar":"^2.0.3","classnames":"^2.2.6","colors":"^1.3.2","commander":"^2.19.0","copy-text-to-clipboard":"^1.0.4","d3-flextree":"^2.1.1","directory-tree":"^2.1.0","file-saver":"^2.0.0","http-server":"^0.11.1","js2flowchart":"^1.1.7","lodash":"^4.17.10","lodash.debounce":"^4.0.8","madge":"^3.3.0","portscanner":"^2.2.0","react":"^16.7.0","react-dom":"^16.7.0","react-draggable":"^3.0.5","react-redux":"^5.0.7","react-syntax-highlighter":"8.0.1","redux":"^4.0.0","redux-persist":"^5.10.0","redux-saga":"^0.16.0","redux-thunk":"^2.2.0","reselect":"^4.0.0","websocket":"^1.0.26"},"devDependencies":{"@babel/core":"^7.1.2","@babel/plugin-syntax-dynamic-import":"^7.2.0","@babel/preset-env":"^7.1.0","@babel/preset-react":"^7.0.0","@commitlint/cli":"^7.3.2","@commitlint/config-conventional":"^7.3.1","babel-loader":"^8.0.4","babel-plugin-import":"^1.9.1","css-loader":"^0.28.11","husky":"^1.3.1","node-sass":"^4.9.3","nodemon":"^1.18.7","prettier":"^1.14.0","sass-loader":"^7.1.0","style-loader":"^0.21.0","webpack":"^4.20.2","webpack-bundle-analyzer":"^3.0.3","webpack-cli":"^3.1.2","webpack-merge":"^4.1.5"},"nodemonConfig":{"ignore":["src/public/**/*.*"],"delay":"2500"},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}}};
4689346893

4689446894
/***/ }),
4689546895

@@ -47994,7 +47994,7 @@ __webpack_require__.r(__webpack_exports__);
4799447994
/* harmony import */ var reselect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! reselect */ "../../node_modules/reselect/es/index.js");
4799547995

4799647996
var getNamespacesList = function getNamespacesList(state) {
47997-
return Object.keys(state.dataBus);
47997+
return Object.keys(state.dataBus).sort();
4799847998
};
4799947999
var getNamespaceState = function getNamespaceState(state) {
4800048000
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

src/public/js/components/treeDiagram/component/Edge/CodeCrumbEdge.js

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export const CodeCrumbedFlowEdge = props => {
6767
y: targetPosition.y + rHalf
6868
};
6969

70-
const padding = 20 - rHalf;
70+
const padding = 21 - rHalf;
7171
const vTurn = 13;
7272

7373
let polylinePoints = [];
@@ -77,13 +77,13 @@ export const CodeCrumbedFlowEdge = props => {
7777
polylinePoints = [
7878
[sourcePt.x, sourcePt.y],
7979
[sourcePt.x, sourcePt.y - padding],
80-
[targetPt.x - 11, sourcePt.y - padding],
81-
[targetPt.x - 11, targetPt.y + vTurn],
82-
[targetPt.x, targetPt.y + vTurn],
80+
[targetPt.x - 12, sourcePt.y - padding],
81+
[targetPt.x - 12, targetPt.y + vTurn - 2],
82+
[targetPt.x, targetPt.y + vTurn - 2],
8383
[targetPt.x, targetPt.y]
8484
];
8585
} else {
86-
const nLength = sourceName.length < 10 ? sourceName.length * SYMBOL_WIDTH + 8 : 100;
86+
const nLength = sourceName.length < 10 ? sourceName.length * SYMBOL_WIDTH + 8 : 120;
8787
polylinePoints = [
8888
[sourcePt.x, sourcePt.y],
8989
[sourcePt.x, sourcePt.y - padding],
@@ -133,3 +133,68 @@ export const CodeCrumbedFlowEdge = props => {
133133
</g>
134134
);
135135
};
136+
137+
export const ExternalEdge = props => {
138+
const {
139+
sourcePosition,
140+
targetPosition,
141+
singleCrumbSource,
142+
singleCrumbTarget,
143+
topBottom,
144+
areaHeight,
145+
firstPart
146+
} = props;
147+
148+
const rHalf = 6;
149+
const sourcePt = {
150+
x: -1 - rHalf + (singleCrumbSource ? sourcePosition.x - 22 : sourcePosition.x),
151+
y: sourcePosition.y - rHalf
152+
};
153+
const targetPt = {
154+
x: -rHalf + (singleCrumbTarget ? targetPosition.x - 22 : targetPosition.x),
155+
y: targetPosition.y
156+
};
157+
158+
const padding = 21 - rHalf;
159+
const vTurn = 13;
160+
161+
const points = firstPart
162+
? [
163+
[sourcePt.x, sourcePt.y],
164+
[sourcePt.x, sourcePt.y - padding],
165+
[targetPt.x - 12, sourcePt.y - padding],
166+
[targetPt.x - 12, topBottom ? areaHeight : 0]
167+
]
168+
: [
169+
[targetPt.x - 12, topBottom ? areaHeight : 0],
170+
[targetPt.x - 12, targetPt.y + vTurn + 3],
171+
[targetPt.x - 2, targetPt.y + vTurn + 4],
172+
[targetPt.x - 2, targetPt.y + vTurn - 1]
173+
];
174+
175+
const iconSize = 8;
176+
return (
177+
<g className={'CodeCrumbEdge'}>
178+
<polyline points={points.join(', ')} className={'CodeCrumbEdge-external-flow'} />
179+
<polyline points={points.join(', ')} className={'CodeCrumbEdge-flow'} />
180+
{firstPart ? (
181+
<rect
182+
x={sourcePt.x - 1}
183+
y={sourcePt.y - 3}
184+
width={3}
185+
height={2}
186+
className={'CodeCrumbEdge-flow-source'}
187+
/>
188+
) : (
189+
<Arrow
190+
x={targetPt.x - 5}
191+
y={targetPt.y + 6}
192+
height={iconSize}
193+
width={iconSize}
194+
isUp={true}
195+
fill={'#e91e63'}
196+
/>
197+
)}
198+
</g>
199+
);
200+
};

src/public/js/components/treeDiagram/component/Edge/index.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@
4949
stroke: #ff18a6;
5050
}
5151

52+
.CodeCrumbEdge-external-flow {
53+
fill: none;
54+
stroke: rgba(255,255,255,0.8);
55+
stroke-width: 4px;
56+
}
57+
5258
.CodeCrumbEdge-flow {
5359
fill: none;
5460
stroke: #ff18a6;

src/public/js/components/treeDiagram/component/Tree/CodeCrumbs/FlowEdge.js

Lines changed: 116 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,30 @@ import React from 'react';
22
import { connect } from 'react-redux';
33

44
import { NO_TRAIL_FLOW } from 'core/constants';
5-
import { CodeCrumbedFlowEdge } from 'components/treeDiagram/component/Edge/CodeCrumbEdge';
5+
import {
6+
CodeCrumbedFlowEdge,
7+
ExternalEdge
8+
} from 'components/treeDiagram/component/Edge/CodeCrumbEdge';
69

710
import { getCheckedState } from 'core/controlsBus/selectors';
8-
import { getSourceLayout, getCodeCrumbsUserChoice } from 'core/dataBus/selectors';
11+
import {
12+
getNamespacesList,
13+
getSourceLayout,
14+
getCodeCrumbsUserChoice
15+
} from 'core/dataBus/selectors';
916

1017
const FlowEdge = props => {
11-
const { shiftToCenterPoint, sortedFlowSteps, filesLayoutMap, codeCrumbsMinimize } = props;
18+
const {
19+
namespace,
20+
areaHeight,
21+
namespacesList,
22+
shiftToCenterPoint,
23+
sortedFlowSteps,
24+
filesLayoutMapNs,
25+
codeCrumbsMinimize
26+
} = props;
27+
28+
const filesLayoutMap = filesLayoutMapNs[namespace];
1229

1330
return (
1431
<React.Fragment>
@@ -17,14 +34,55 @@ const FlowEdge = props => {
1734
if (!i) return null;
1835

1936
const fromItem = list[i - 1];
20-
const fromFile = filesLayoutMap[fromItem.filePath];
21-
const toFile = filesLayoutMap[toItem.filePath];
37+
if (fromItem.namespace !== namespace && toItem.namespace !== namespace) {
38+
return null;
39+
}
2240

2341
const edgePoints = [fromItem, toItem].map(crumb => {
2442
const [cX, cY] = [crumb.y, crumb.x];
2543
return shiftToCenterPoint(cX, cY);
2644
});
2745

46+
const namespaceIndex = namespacesList.indexOf(namespace);
47+
48+
if (fromItem.namespace === namespace && toItem.namespace !== namespace) {
49+
const fromFile = filesLayoutMap[fromItem.filePath];
50+
const toFile = filesLayoutMapNs[toItem.namespace][toItem.filePath];
51+
52+
return (
53+
<ExternalEdge
54+
key={`cc-external-edge-${fromItem.name}-${toItem.name}`}
55+
sourcePosition={edgePoints[0]}
56+
targetPosition={edgePoints[1]}
57+
singleCrumbSource={fromFile.children.length === 1}
58+
singleCrumbTarget={toFile.children.length === 1}
59+
areaHeight={areaHeight}
60+
topBottom={namespaceIndex < namespacesList.indexOf(toItem.namespace)}
61+
firstPart={true}
62+
/>
63+
);
64+
}
65+
66+
if (fromItem.namespace !== namespace && toItem.namespace === namespace) {
67+
const fromFile = filesLayoutMapNs[fromItem.namespace][fromItem.filePath];
68+
const toFile = filesLayoutMap[toItem.filePath];
69+
70+
return (
71+
<ExternalEdge
72+
key={`cc-external-edge-${fromItem.name}-${toItem.name}`}
73+
sourcePosition={edgePoints[0]}
74+
targetPosition={edgePoints[1]}
75+
singleCrumbSource={fromFile.children.length === 1}
76+
singleCrumbTarget={toFile.children.length === 1}
77+
areaHeight={areaHeight}
78+
topBottom={namespaceIndex < namespacesList.indexOf(fromItem.namespace)}
79+
/>
80+
);
81+
}
82+
83+
const fromFile = filesLayoutMap[fromItem.filePath];
84+
const toFile = filesLayoutMap[toItem.filePath];
85+
2886
return (
2987
<CodeCrumbedFlowEdge
3088
key={`cc-flow-edge-${fromItem.name}-${toItem.name}`}
@@ -41,13 +99,23 @@ const FlowEdge = props => {
4199
);
42100
};
43101

44-
const getSortedFlowSteps = ({ codeCrumbedFlowsMap, selectedCrumbedFlowKey, filesLayoutMap }) => {
102+
const stepSorter = (a, b) => a.step - b.step;
103+
104+
// TODO: this should be done in reducer
105+
const getSortedFlowSteps = ({
106+
namespace,
107+
codeCrumbedFlowsMap,
108+
selectedCrumbedFlowKey,
109+
filesLayoutMap
110+
}) => {
45111
const currentFlow = codeCrumbedFlowsMap[selectedCrumbedFlowKey] || {};
46112
let sortedFlowSteps = [];
113+
47114
Object.keys(currentFlow).forEach(filePath => {
48115
const steps = ((filesLayoutMap[filePath] && filesLayoutMap[filePath].children) || [])
49116
.filter(({ data }) => data.params.flow === selectedCrumbedFlowKey)
50117
.map(({ data, x, y }) => ({
118+
namespace,
51119
name: data.name,
52120
filePath,
53121
step: data.params.flowStep,
@@ -59,37 +127,59 @@ const getSortedFlowSteps = ({ codeCrumbedFlowsMap, selectedCrumbedFlowKey, files
59127
sortedFlowSteps = sortedFlowSteps.concat(steps);
60128
});
61129

62-
sortedFlowSteps.sort((a, b) => a.step - b.step);
130+
sortedFlowSteps.sort(stepSorter);
63131

64132
return sortedFlowSteps;
65133
};
66134

67135
const mapStateToProps = (state, props) => {
68136
const { codeCrumbsMinimize } = getCheckedState(state);
69-
137+
const namespacesList = getNamespacesList(state);
70138
const { namespace } = props;
71-
const namespaceProps = { namespace };
72139

73-
const { filesLayoutMap } = getSourceLayout(state, namespaceProps);
74-
const { selectedCrumbedFlowKey, codeCrumbedFlowsMap } = getCodeCrumbsUserChoice(
75-
state,
76-
namespaceProps
77-
);
140+
const { selectedCrumbedFlowKey: currentSelectedCrumbedFlowKey } = getCodeCrumbsUserChoice(state, {
141+
namespace
142+
});
78143

79-
// TODO: ftw is this
80-
const sortedFlowSteps =
81-
selectedCrumbedFlowKey !== NO_TRAIL_FLOW
82-
? getSortedFlowSteps({
83-
codeCrumbedFlowsMap,
84-
selectedCrumbedFlowKey,
85-
filesLayoutMap
86-
})
87-
: [];
144+
const gatheredFlowsData = namespacesList.reduce(
145+
(acc, ns) => {
146+
const namespaceProps = { namespace: ns };
147+
const { selectedCrumbedFlowKey, codeCrumbedFlowsMap } = getCodeCrumbsUserChoice(
148+
state,
149+
namespaceProps
150+
);
151+
152+
if (currentSelectedCrumbedFlowKey !== selectedCrumbedFlowKey) {
153+
return acc;
154+
}
155+
156+
const { filesLayoutMap } = getSourceLayout(state, namespaceProps);
157+
158+
const sortedFlowSteps =
159+
selectedCrumbedFlowKey !== NO_TRAIL_FLOW
160+
? getSortedFlowSteps({
161+
namespace: ns,
162+
codeCrumbedFlowsMap,
163+
selectedCrumbedFlowKey,
164+
filesLayoutMap
165+
})
166+
: [];
167+
168+
return {
169+
sortedFlowSteps: [...acc.sortedFlowSteps, ...sortedFlowSteps].sort(stepSorter),
170+
filesLayoutMapNs: {
171+
...acc.filesLayoutMapNs,
172+
[ns]: filesLayoutMap
173+
}
174+
};
175+
},
176+
{ filesLayoutMapNs: {}, sortedFlowSteps: [] }
177+
);
88178

89179
return {
90-
sortedFlowSteps,
91-
filesLayoutMap,
92-
codeCrumbsMinimize
180+
namespacesList,
181+
codeCrumbsMinimize,
182+
...gatheredFlowsData
93183
};
94184
};
95185

src/public/js/components/treeDiagram/component/Tree/Source/Tree.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const SourceTree = props => {
2020
codeCrumbsDiagramOn,
2121
codeCrumbsMinimize,
2222

23+
areaHeight,
2324
sourceLayoutTree,
2425
openedFolders,
2526
filesMap,
@@ -134,7 +135,11 @@ const SourceTree = props => {
134135
)}
135136

136137
{(codeCrumbsDiagramOn && (
137-
<CodeCrumbedFlowEdges namespace={namespace} shiftToCenterPoint={shiftToCenterPoint} />
138+
<CodeCrumbedFlowEdges
139+
namespace={namespace}
140+
shiftToCenterPoint={shiftToCenterPoint}
141+
areaHeight={areaHeight}
142+
/>
138143
)) ||
139144
null}
140145

0 commit comments

Comments
 (0)